11 #include "CallAppFrame.h"
12 #include "CallPresentationModel.h"
13 #include "CallTypes.h"
14 #include "CallAppUtility.h"
15 #include "CallIAppStateChangeListner.h"
17 using namespace Tizen::App;
18 using namespace Tizen::Base;
19 using namespace Tizen::System;
20 using namespace Tizen::Ui;
21 using namespace Tizen::Ui::Controls;
22 using namespace Tizen::Ui::Scenes;
23 using namespace Tizen::Base::Utility;
24 using namespace Tizen::Base::Collection;
25 using namespace Tizen::Base::Utility;
26 using namespace Tizen::Shell;
29 CallApp::CallApp(void):__initialSceneId(L""), __pLaunchArgs(null)
31 __listenerList.Construct();
34 CallApp::~CallApp(void)
39 CallApp::CreateInstance(void)
41 // Create the instance through the constructor.
46 CallApp::OnAppInitializing(AppRegistry& appRegistry)
48 AppControlProviderManager* pProviderMgr = AppControlProviderManager::GetInstance();
49 pProviderMgr->SetAppControlProviderEventListener(this);
54 CallApp::OnAppInitialized(void)
60 CallAppFrame* pCallAppFrame = new CallAppFrame();
61 pCallAppFrame->Construct();
62 pCallAppFrame->SetName(L"CallApp");
63 AddFrame(*pCallAppFrame);
65 //Check if there is no initial scene, then exit application.
66 //This case will normally come when invalid AppControl request has come,
67 //or incoming call is coming from unknown number and "reject unknown number" settings is enabled.
68 if (GetInitialScene().IsEmpty() == true)
77 CallApp::OnAppWillTerminate(void)
85 CallApp::OnAppTerminating(AppRegistry& appRegistry, bool forcedTermination)
88 // Deallocate resources allocated by this App for termination.
89 // The App's permanent data and context can be saved via appRegistry.
94 CallApp::OnForeground(void)
96 IEnumerator* pEnum = __listenerList.GetEnumeratorN();
97 while (pEnum->MoveNext() == E_SUCCESS)
99 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
100 if (pInterface == null)
106 pInterface->OnForeground();
112 CallApp::OnBackground(void)
115 // Stop drawing when the application is moved to the background.
119 CallApp::OnLowMemory(void)
122 // Free unused resources or close the application.
126 CallApp::OnBatteryLevelChanged(BatteryLevel batteryLevel)
129 // Handle any changes in battery level here.
130 // Stop using multimedia features(camera, mp3 etc.) if the battery level is CRITICAL.
134 CallApp::OnScreenOn(void)
137 // Get the released resources or resume the operations that were paused or stopped in OnScreenOff().
141 CallApp::OnScreenOff(void)
144 // Unless there is a strong reason to do otherwise, release resources (such as 3D, media, and sensors) to allow the device
145 // to enter the sleep mode to save the battery.
146 // Invoking a lengthy asynchronous method within this listener method can be risky, because it is not guaranteed to invoke a
147 // callback before the device enters the sleep mode.
148 // Similarly, do not perform lengthy operations in this listener method. Any operation must be a quick one.
152 CallApp::GetInitialScene(void)
154 return __initialSceneId;
158 CallApp::GetAppLaunchArguments(void)
160 return __pLaunchArgs;
164 CallApp::AddAppStateChangeListener(const IAppStateChangeListener& listener)
166 __listenerList.Add(listener);
170 CallApp::RemoveAppStateChangeListener(const IAppStateChangeListener& listener)
172 __listenerList.Remove(listener);
176 CallApp::OnAppControlRequestReceived(RequestId reqId, const String& operationId, const String* pUriData,
177 const String* pMimeType, const IMap* pExtraData)
179 AppLogDebug("Enter ");
182 AppLogDebug("%ls ",pUriData->GetPointer());
185 if(pExtraData == null && pUriData != null)
187 //The request is from web app
188 AppLogDebug("%ls",pUriData->GetPointer());
189 ProcessWebAppControlRequest(reqId, operationId, pUriData);
193 //process AppControl parameters
194 ProcessAppControlRequest(reqId, operationId, pExtraData,pUriData);
200 CallApp::ProcessWebAppControlRequest(RequestId reqId, const String& operationId,const String* pUriData)
202 //Construct map from string
203 String delim(DELIMITER);
204 StringTokenizer st(*pUriData,delim);
207 extraData.Construct();
208 while(st.HasMoreTokens())
212 st.GetNextToken(token);
215 if(st.HasMoreTokens())
218 st.GetNextToken(token);
222 extraData.Add(new (std::nothrow) String(key), new (std::nothrow) String(value));
225 //Adding this explicitly as there no other way to invoke call from webapp
226 extraData.Add(new (std::nothrow) String(PARAM_CALL_TYPE), new (std::nothrow) String(PARAM_CALL_VALUE_VOICE));
228 ProcessAppControlRequest(reqId,operationId,&extraData);
230 extraData.RemoveAll(true);
234 CallApp::ProcessAppControlRequest(RequestId reqId, const String& operationId,const IMap* pArgsMap,const String* pUriData)
236 AppLogDebug("Enter %ls",operationId.GetPointer());
237 __pLaunchArgs = null;
238 if(operationId.Equals(OPERATION_ID_CALL,true) == true)
240 AppLogDebug("OPERATION_ID_CALL");
243 bool isIncomingCallRequest = false;
244 String* pKey = new (std::nothrow) String(LAUNCHTYPE);
245 if (pArgsMap->ContainsKey(*pKey) == true)
247 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
248 if ((pValue != null) && (pValue->Equals(PARAM_ORIGIN_MT, true) == true))
250 isIncomingCallRequest = true;
253 //Check if incoming call request or outgoing call request
254 if(isIncomingCallRequest == true)
256 HandleIncomingCallAppControlRequest(reqId, pArgsMap);
260 HandleDialCallAppControlRequest(reqId, pArgsMap,pUriData);
265 AppLogDebug("pArgsMap == null");
271 CallApp::HandleIncomingCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
273 AppLogDebug("Enter");
274 SceneManager* pSceneManager = SceneManager::GetInstance();
276 AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
279 String callHandle(L"");
280 String* pKey = new (std::nothrow) String(CALL_HANDLE);
281 if (pArgsMap->ContainsKey(*pKey) == true)
283 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
286 callHandle.Append(*pValue);
291 String contactNumber(L"");
292 pKey = new (std::nothrow) String(CONTACT_NUMBER);
293 if (pArgsMap->ContainsKey(*pKey) == true)
295 const String* pContactValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
296 if (pContactValue != null)
298 contactNumber.Append(*pContactValue);
299 AppLogDebug("%ls",contactNumber.GetPointer());
305 //Fetch incoming call details
306 CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
307 AppCallInfo* pIncomingCall = pCallPresentor->FetchIncomingCallDetailsN(callHandle, contactNumber);
308 if(pIncomingCall != null)
310 bool isCallRejected = pCallPresentor->CheckIncomingCallToBeRejected(pIncomingCall);
311 if(isCallRejected == false)
313 //save app launch argument list
314 __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
315 __pLaunchArgs->Construct(1);
316 __pLaunchArgs->Add(pIncomingCall);
317 if(__initialSceneId.IsEmpty() == true)
319 __initialSceneId = IDSCN_SCENE_INCOMINGCALL;
323 //App already initialized, goto incoming call form
324 pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL), __pLaunchArgs);
325 __pLaunchArgs = null;
330 //Show messageBox showing automatic call rejection
331 /* MessageBox callRejectedInoMsgBox;
332 String msg(L"Call From ");
333 msg.Append(contactNumber);
334 msg.Append(L" Rejected.");
335 callRejectedInoMsgBox.Construct(L"Call Rejected", msg, MSGBOX_STYLE_NONE,1000);
337 // Calls ShowAndWait() : Draws and Shows itself and processes events
338 callRejectedInoMsgBox.ShowAndWait(modalResult);*/
340 //go back to previous scene if App was already running, else exit application.
341 if(__initialSceneId.IsEmpty() == true)
343 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
344 AppLog("Terminate Phone Application");
349 //set success message
350 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
354 appControlResult = APP_CTRL_RESULT_FAILED;
356 AppLogDebug("Exiting %d",appControlResult);
357 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
361 CallApp::HandleDialCallAppControlRequest(RequestId reqId,const IMap* pArgsMap,const String* pUriData)
364 AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
366 if (pArgsMap != null)
368 String callType(L"");
369 String phoneNumber(L"");
371 String* pKey = new (std::nothrow) String(PARAM_PHONE_NUMBER);
372 if(pArgsMap->ContainsKey(*pKey) == true)
374 const String* pPhoneValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
375 if(pPhoneValue != null)
377 AppLogDebug("%ls",pPhoneValue->GetPointer());
378 phoneNumber.Append(*pPhoneValue);
383 AppLogDebug("PARAM_PHONE_NUMBER not present");
384 //Now check if tel uri is present
387 AppLogDebug("pUriData is present %ls",pUriData->GetPointer());
388 phoneNumber.Append(*pUriData);
389 if(phoneNumber.Contains(PARAM_PHONE_NUMBER))
391 phoneNumber.Replace(PARAM_PHONE_NUMBER,L"");
392 if(phoneNumber.Contains(DELIMITER))
394 phoneNumber.Replace(DELIMITER,L"");
395 AppLogDebug("%ls",phoneNumber.GetPointer());
398 AppLogDebug("%ls",phoneNumber.GetPointer());
402 //Check if its a valid number
403 if(CheckNumberIsValid(phoneNumber) == false)
405 //Show messageBox showing automatic call rejection
406 MessageBox InvalidNumberMsgBox;
407 InvalidNumberMsgBox.Construct(AppUtility::GetResourceString(IDS_INVALID_NUMBER), L"",MSGBOX_STYLE_NONE,1000);
409 // Calls ShowAndWait() : Draws and Shows itself and processes events
410 InvalidNumberMsgBox.ShowAndWait(modalResult);
412 //go back to previous scene if App was already running, else exit application.
413 if(__initialSceneId.IsEmpty() == true)
415 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
416 AppLog("Terminate Phone Application");
417 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
424 pKey = new (std::nothrow) String(PARAM_CALL_TYPE);
425 if(pArgsMap->ContainsKey(*pKey) == true)
427 const String* pCallTypeValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
428 if(pCallTypeValue != null)
430 callType.Append(*pCallTypeValue);
436 //Fetch currently active call count
437 if (callType.IsEmpty() == false
438 && callType.Equals(PARAM_CALL_VALUE_VOICE, false) == true
439 && phoneNumber.IsEmpty() == false)
441 SceneManager* pSceneManager = SceneManager::GetInstance();
442 //check if there is already a call in dialing mode, then dont accept any other dialing request.
443 if (pSceneManager->GetCurrentSceneId() == IDSCN_SCENE_OUTCALL
444 || pSceneManager->GetCurrentSceneId()
445 == IDSCN_SCENE_OUT_EMERGENCYCALL)
448 appControlResult = APP_CTRL_RESULT_CANCELED;
449 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
452 CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
453 int currentActiveCallCount = pCallPresentor->GetCurrentCallCount();
454 if(currentActiveCallCount <= 1)
456 //make an outgoing call with given number
457 String* contactTxt = new (std::nothrow) String(phoneNumber);
458 __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
459 __pLaunchArgs->Construct();
460 __pLaunchArgs->Add(contactTxt);
461 bool isEmergencyCall = pCallPresentor->IsEmergencyNumber(*contactTxt, true);
463 SceneId nextScene = IDSCN_SCENE_OUTCALL;
466 nextScene = IDSCN_SCENE_OUT_EMERGENCYCALL;
468 //Check if app was already running
469 if(__initialSceneId.IsEmpty() == true)
471 //phone App is not already launched
472 __initialSceneId = nextScene;
476 AppLog("Outgoing call");
477 pSceneManager->GoForward( ForwardSceneTransition( nextScene), __pLaunchArgs);
479 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
483 //already 2 active calls, 3rd call not allowed
484 appControlResult = APP_CTRL_RESULT_CANCELED;
489 appControlResult = APP_CTRL_RESULT_FAILED;
492 //send response message
493 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
497 CallApp::CheckNumberIsValid(String phoneNumber)
499 //Pattern to compare all characters except 0-9 * # P ; , +
500 String phoneNumberPattern(L"[^0-9*#P,+;]");
501 RegularExpression checkPhoneNumber;
502 checkPhoneNumber.Construct(phoneNumberPattern);
503 //If there is any character other than these listed above then display invalid number
504 bool resultMatch = checkPhoneNumber.Match(phoneNumber,false);
505 //return false for patterns other than 0-9 * # P ; , +
511 CallApp::SetTopMostWindow(bool bTopMost)
513 AppLogDebug("bTopMost = %d",bTopMost);
514 result res = E_FAILURE;
515 //ToDO: Need to see if there is better way to handle
520 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_HIGHEST);
521 if(PowerManager::IsScreenOn() == false)
523 res = PowerManager::TurnScreenOn();
525 res = PowerManager::KeepScreenOnState(true,false);
530 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_NORMAL);
531 PowerManager::KeepScreenOnState(false);
533 //Unlock the phone if its locked
534 if(LockManager::GetInstance()->IsLocked())
536 LockManager::GetInstance()->Unlock();