Fix for N_SE-28854 N_SE-29290 N_SE-27358 N_SE-25429 N_SE-25498 N_SE-25689 N_SE-27155...
[apps/osp/Call.git] / src / CallApp.cpp
1 /**
2  * Name        : CallApp
3  * Version     :
4  * Vendor      :
5  * Description :
6  */
7
8 #include <FUi.h>
9 #include "CallApp.h"
10 #include "CallAppFrame.h"
11 #include "CallPresentationModel.h"
12 #include "CallTypes.h"
13 #include "CallAppUtility.h"
14 #include "CallIAppStateChangeListner.h"
15
16 using namespace Tizen::App;
17 using namespace Tizen::Base;
18 using namespace Tizen::System;
19 using namespace Tizen::Ui;
20 using namespace Tizen::Ui::Controls;
21 using namespace Tizen::Ui::Scenes;
22 using namespace Tizen::Base::Utility;
23 using namespace Tizen::Base::Collection;
24 using namespace Tizen::Base::Utility;
25
26
27 CallApp::CallApp(void):__initialSceneId(L""), __pLaunchArgs(null)
28 {
29         __listenerList.Construct();
30 }
31
32 CallApp::~CallApp(void)
33 {
34 }
35
36 UiApp*
37 CallApp::CreateInstance(void)
38 {
39         // Create the instance through the constructor.
40         return new CallApp();
41 }
42
43 bool
44 CallApp::OnAppInitializing(AppRegistry& appRegistry)
45 {
46         AppControlProviderManager* pProviderMgr = AppControlProviderManager::GetInstance();
47         pProviderMgr->SetAppControlProviderEventListener(this);
48         return true;
49 }
50
51 bool
52 CallApp::OnAppInitialized(void)
53 {
54         // TODO:
55         // Comment.
56
57         // Create a Frame
58         CallAppFrame* pCallAppFrame = new CallAppFrame();
59         pCallAppFrame->Construct();
60         pCallAppFrame->SetName(L"CallApp");
61         AddFrame(*pCallAppFrame);
62
63         //Check if there is no initial scene, then exit application.
64         //This case will normally come when invalid AppControl request has come,
65         //or incoming call is coming from unknown number and "reject unknown number" settings is enabled.
66         if (GetInitialScene().IsEmpty() == true)
67         {
68                 return false;
69         }
70
71         return true;
72 }
73
74 bool
75 CallApp::OnAppWillTerminate(void)
76 {
77         // TODO:
78         // Comment.
79         return true;
80 }
81
82 bool
83 CallApp::OnAppTerminating(AppRegistry& appRegistry, bool forcedTermination)
84 {
85         // TODO:
86         // Deallocate resources allocated by this App for termination.
87         // The App's permanent data and context can be saved via appRegistry.
88         return true;
89 }
90
91 void
92 CallApp::OnForeground(void)
93 {
94         IEnumerator* pEnum = __listenerList.GetEnumeratorN();
95         while (pEnum->MoveNext() == E_SUCCESS)
96         {
97                 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
98                 if (pInterface == null)
99                 {
100                         delete pEnum;
101
102                         return;
103                 }
104                 pInterface->OnForeground();
105         }
106         delete pEnum;
107 }
108
109 void
110 CallApp::OnBackground(void)
111 {
112         // TODO:
113         // Stop drawing when the application is moved to the background.
114 }
115
116 void
117 CallApp::OnLowMemory(void)
118 {
119         // TODO:
120         // Free unused resources or close the application.
121 }
122
123 void
124 CallApp::OnBatteryLevelChanged(BatteryLevel batteryLevel)
125 {
126         // TODO:
127         // Handle any changes in battery level here.
128         // Stop using multimedia features(camera, mp3 etc.) if the battery level is CRITICAL.
129 }
130
131 void
132 CallApp::OnScreenOn(void)
133 {
134         // TODO:
135         // Get the released resources or resume the operations that were paused or stopped in OnScreenOff().
136 }
137
138 void
139 CallApp::OnScreenOff(void)
140 {
141         // TODO:
142         // Unless there is a strong reason to do otherwise, release resources (such as 3D, media, and sensors) to allow the device
143         // to enter the sleep mode to save the battery.
144         // Invoking a lengthy asynchronous method within this listener method can be risky, because it is not guaranteed to invoke a
145         // callback before the device enters the sleep mode.
146         // Similarly, do not perform lengthy operations in this listener method. Any operation must be a quick one.
147 }
148
149 SceneId
150 CallApp::GetInitialScene(void)
151 {
152         return __initialSceneId;
153 }
154
155 IList*
156 CallApp::GetAppLaunchArguments(void)
157 {
158         return __pLaunchArgs;
159 }
160
161 void
162 CallApp::AddAppStateChangeListener(const IAppStateChangeListener& listener)
163 {
164         __listenerList.Add(listener);
165
166 }
167 void
168 CallApp::RemoveAppStateChangeListener(const IAppStateChangeListener& listener)
169 {
170         __listenerList.Remove(listener);
171 }
172
173 void
174 CallApp::OnAppControlRequestReceived(RequestId reqId, const String& operationId, const String* pUriData,
175                 const String* pMimeType, const IMap* pExtraData)
176 {
177         AppLogDebug("ENTER");
178         //process AppControl parameters
179         ProcessAppControlRequest(reqId, operationId, pExtraData);
180         AppLogDebug("EXIT");
181 }
182
183 void
184 CallApp::ProcessAppControlRequest(RequestId reqId, const String& operationId,const IMap* pArgsMap)
185 {
186         AppLogDebug("Enter %ls",operationId.GetPointer());
187         __pLaunchArgs = null;
188         if(operationId.Equals(OPERATION_ID_CALL,true) == true)
189         {
190                 AppLogDebug("OPERATION_ID_CALL");
191                 if(pArgsMap != null)
192                 {
193                         bool isIncomingCallRequest = false;
194                         String* pKey = new (std::nothrow) String(LAUNCHTYPE);
195                         if (pArgsMap->ContainsKey(*pKey) == true)
196                         {
197                                 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
198                                 if ((pValue != null) && (pValue->Equals(PARAM_ORIGIN_MT, true) == true))
199                                 {
200                                         isIncomingCallRequest = true;
201                                 }
202                         }
203                         //Check if incoming call request or outgoing call request
204                         if(isIncomingCallRequest == true)
205                         {
206                                 HandleIncomingCallAppControlRequest(reqId, pArgsMap);
207                         }
208                         else
209                         {
210                                 HandleDialCallAppControlRequest(reqId, pArgsMap);
211                         }
212                 }
213                 else
214                 {
215                         AppLogDebug("pArgsMap == null");
216                 }
217         }
218 }
219
220 void
221 CallApp::HandleIncomingCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
222 {
223         AppLogDebug("Enter");
224         SceneManager* pSceneManager = SceneManager::GetInstance();
225         //response message
226         AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
227
228         //call handle
229         String callHandle(L"");
230         String* pKey = new (std::nothrow) String(CALL_HANDLE);
231         if (pArgsMap->ContainsKey(*pKey) == true)
232         {
233                 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
234                 if (pValue != null)
235                 {
236                         callHandle.Append(*pValue);
237                 }
238         }
239         delete pKey;
240         //contact number
241         String contactNumber(L"");
242         pKey = new (std::nothrow) String(CONTACT_NUMBER);
243         if (pArgsMap->ContainsKey(*pKey) == true)
244         {
245                 const String* pContactValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
246                 if (pContactValue != null)
247                 {
248                         contactNumber.Append(*pContactValue);
249                         AppLogDebug("%ls",contactNumber.GetPointer());
250                 }
251         }
252         delete pKey;
253         pKey = null;
254
255         //Fetch incoming call details
256         CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
257         CallInfo* pIncomingCall = pCallPresentor->FetchIncomingCallDetailsN(callHandle, contactNumber);
258         if(pIncomingCall != null)
259         {
260                 bool isCallRejected = pCallPresentor->CheckIncomingCallToBeRejected(pIncomingCall);
261                 if(isCallRejected == false)
262                 {
263                         //save app launch argument list
264                         __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
265                         __pLaunchArgs->Construct(1);
266                         __pLaunchArgs->Add(pIncomingCall);
267                         if(__initialSceneId.IsEmpty() == true)
268                         {
269                                 __initialSceneId = IDSCN_SCENE_INCOMINGCALL;
270                         }
271                         else
272                         {
273                                 //App already initialized, goto incoming call form
274                                 pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL), __pLaunchArgs);
275                                 __pLaunchArgs = null;
276                         }
277                 }
278                 else
279                 {
280                         //Show messageBox showing automatic call rejection
281                         MessageBox callRejectedInoMsgBox;
282                         String msg(L"Call From ");
283                         msg.Append(contactNumber);
284                         msg.Append(L" Rejected.");
285                         callRejectedInoMsgBox.Construct(L"Call Rejected", msg, MSGBOX_STYLE_NONE,1000);
286                         int modalResult = 0;
287                         // Calls ShowAndWait() : Draws and Shows itself and processes events
288                         callRejectedInoMsgBox.ShowAndWait(modalResult);
289
290                         //go back to previous scene if App was already running, else exit application.
291                         if(__initialSceneId.IsEmpty() == true)
292                         {
293                                 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
294                                 AppLog("Terminate Phone Application");
295                                 Terminate();
296                         }
297
298                 }
299                 //set success message
300                 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
301         }
302         else
303         {
304                 appControlResult = APP_CTRL_RESULT_FAILED;
305         }
306         AppLogDebug("Exiting %d",appControlResult);
307         AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
308 }
309
310 void
311 CallApp::HandleDialCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
312 {
313         //response message
314         AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
315
316         if (pArgsMap != null)
317         {
318                 String callType(L"");
319                 String phoneNumber(L"");
320                 //phone number
321                 String* pKey = new (std::nothrow) String(PARAM_PHONE_NUMBER);
322                 if(pArgsMap->ContainsKey(*pKey) == true)
323                 {
324                         const String* pPhoneValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
325                         if(pPhoneValue != null)
326                         {
327                                 AppLogDebug("%ls",pPhoneValue->GetPointer());
328                                 phoneNumber.Append(*pPhoneValue);
329                         }
330                 }
331                 else
332                 {
333                         AppLogDebug("PARAM_PHONE_NUMBER not present");
334                 }
335                 delete pKey;
336                 //Check if its a valid number
337                 if(CheckNumberIsValid(phoneNumber) == false)
338                 {
339                         //Show messageBox showing automatic call rejection
340                         MessageBox InvalidNumberMsgBox;
341                         InvalidNumberMsgBox.Construct(AppUtility::GetResourceString(IDS_INVALID_NUMBER), L"",MSGBOX_STYLE_NONE,1000);
342                         int modalResult = 0;
343                         // Calls ShowAndWait() : Draws and Shows itself and processes events
344                         InvalidNumberMsgBox.ShowAndWait(modalResult);
345
346                         //go back to previous scene if App was already running, else exit application.
347                         if(__initialSceneId.IsEmpty() == true)
348                         {
349                                 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
350                                 AppLog("Terminate Phone Application");
351                                 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
352                                 Terminate();
353                                 return;
354                         }
355
356                 }
357                 //call type
358                 pKey = new (std::nothrow) String(PARAM_CALL_TYPE);
359                 if(pArgsMap->ContainsKey(*pKey) == true)
360                 {
361                         const String* pCallTypeValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
362                         if(pCallTypeValue != null)
363                         {
364                                 callType.Append(*pCallTypeValue);
365                         }
366                 }
367                 delete pKey;
368                 pKey = null;
369
370                 //Fetch currently active call count
371                 if (callType.IsEmpty() == false
372                                 && callType.Equals(PARAM_CALL_VALUE_VOICE, false) == true
373                                 && phoneNumber.IsEmpty() == false)
374                 {
375                         SceneManager* pSceneManager = SceneManager::GetInstance();
376                         //check if there is already a call in dialing mode, then dont accept any other dialing request.
377                         if (pSceneManager->GetCurrentSceneId() == IDSCN_SCENE_OUTCALL
378                                         || pSceneManager->GetCurrentSceneId()
379                                                         == IDSCN_SCENE_OUT_EMERGENCYCALL)
380                         {
381                                 AppLog("Cancelled");
382                                 appControlResult = APP_CTRL_RESULT_CANCELED;
383                                 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
384                                 return;
385                         }
386                         CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
387                         int currentActiveCallCount = pCallPresentor->GetCurrentCallCount();
388                         if(currentActiveCallCount <= 1)
389                         {
390                                 //make an outgoing call with given number
391                                 String* contactTxt = new (std::nothrow) String(phoneNumber);
392                                 __pLaunchArgs =  new (std::nothrow) ArrayList(SingleObjectDeleter);
393                                 __pLaunchArgs->Construct();
394                                 __pLaunchArgs->Add(contactTxt);
395                                 bool isEmergencyCall = pCallPresentor->IsEmergencyNumber(*contactTxt, true);
396
397                                 SceneId nextScene = IDSCN_SCENE_OUTCALL;
398                                 if (isEmergencyCall)
399                                 {
400                                         nextScene = IDSCN_SCENE_OUT_EMERGENCYCALL;
401                                 }
402                                 //Check if app was already running
403                                 if(__initialSceneId.IsEmpty() == true)
404                                 {
405                                         //phone App is not already launched
406                                         __initialSceneId = nextScene;
407                                 }
408                                 else
409                                 {
410                                         AppLog("Outgoing call");
411                                         pSceneManager->GoForward( ForwardSceneTransition( nextScene), __pLaunchArgs);
412                                 }
413                                 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
414                         }
415                         else
416                         {
417                                 //already 2 active calls, 3rd call not allowed
418                                 appControlResult = APP_CTRL_RESULT_CANCELED;
419                         }
420                 }
421                 else
422                 {
423                         appControlResult = APP_CTRL_RESULT_FAILED;
424                 }
425         }
426         //send response message
427         AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
428 }
429
430 bool
431 CallApp::CheckNumberIsValid(String phoneNumber)
432 {
433         //Pattern to compare all characters except 0-9 * # P ; , +
434         String phoneNumberPattern(L"[^0-9*#P,+]");
435         RegularExpression checkPhoneNumber;
436         checkPhoneNumber.Construct(phoneNumberPattern);
437         //If there is any character other than these listed above then display invalid number
438         bool resultMatch = checkPhoneNumber.Match(phoneNumber,false);
439         //return false for patterns other than 0-9 * # P ; , +
440         return !resultMatch;
441
442 }
443
444 void
445 CallApp::SetTopMostWindow(bool bTopMost)
446 {
447         AppLogDebug("bTopMost = %d",bTopMost);
448         result res = E_FAILURE;
449         //ToDO: Need to see if there is better way to handle
450         //this case
451         if(bTopMost == true)
452         {
453                 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_HIGH);
454                 if(PowerManager::IsScreenOn() == false)
455                 {
456                         res = PowerManager::TurnScreenOn();
457                 }
458                 res = PowerManager::KeepScreenOnState(true,false);
459
460         }
461         else
462         {
463                 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_NORMAL);
464                 PowerManager::KeepScreenOnState(false);
465         }
466
467 }