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;
28 CallApp::CallApp(void):__initialSceneId(L""), __pLaunchArgs(null)
30 __listenerList.Construct();
33 CallApp::~CallApp(void)
38 CallApp::CreateInstance(void)
40 // Create the instance through the constructor.
45 CallApp::OnAppInitializing(AppRegistry& appRegistry)
47 AppControlProviderManager* pProviderMgr = AppControlProviderManager::GetInstance();
48 pProviderMgr->SetAppControlProviderEventListener(this);
49 PowerManager::AddScreenEventListener(*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.
90 PowerManager::RemoveScreenEventListener(*this);
95 CallApp::OnForeground(void)
97 IEnumerator* pEnum = __listenerList.GetEnumeratorN();
98 while (pEnum->MoveNext() == E_SUCCESS)
100 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
101 if (pInterface == null)
107 pInterface->OnForeground();
113 CallApp::OnBackground(void)
116 // Stop drawing when the application is moved to the background.
120 CallApp::OnLowMemory(void)
123 // Free unused resources or close the application.
127 CallApp::OnBatteryLevelChanged(BatteryLevel batteryLevel)
130 // Handle any changes in battery level here.
131 // Stop using multimedia features(camera, mp3 etc.) if the battery level is CRITICAL.
135 CallApp::OnScreenOn(void)
138 // Get the released resources or resume the operations that were paused or stopped in OnScreenOff().
142 CallApp::OnScreenOff(void)
144 AppLogDebug("Enter");
145 IEnumerator* pEnum = __listenerList.GetEnumeratorN();
146 while (pEnum->MoveNext() == E_SUCCESS)
148 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
149 if (pInterface == null)
155 pInterface->OnScreenOff();
162 CallApp::GetInitialScene(void)
164 return __initialSceneId;
168 CallApp::GetAppLaunchArguments(void)
170 return __pLaunchArgs;
174 CallApp::AddAppStateChangeListener(const IAppStateChangeListener& listener)
176 __listenerList.Add(listener);
180 CallApp::RemoveAppStateChangeListener(const IAppStateChangeListener& listener)
182 __listenerList.Remove(listener);
186 CallApp::OnAppControlRequestReceived(RequestId reqId, const String& operationId, const String* pUriData,
187 const String* pMimeType, const IMap* pExtraData)
189 AppLogDebug("Enter ");
192 AppLogDebug("%ls ",pUriData->GetPointer());
195 if(pExtraData == null && pUriData != null)
197 //The request is from web app
198 AppLogDebug("%ls",pUriData->GetPointer());
199 ProcessWebAppControlRequest(reqId, operationId, pUriData);
203 //process AppControl parameters
204 ProcessAppControlRequest(reqId, operationId, pExtraData,pUriData);
210 CallApp::ProcessWebAppControlRequest(RequestId reqId, const String& operationId,const String* pUriData)
212 //Construct map from string
213 String delim(DELIMITER);
214 StringTokenizer st(*pUriData,delim);
217 extraData.Construct();
218 while(st.HasMoreTokens())
222 st.GetNextToken(token);
225 if(st.HasMoreTokens())
228 st.GetNextToken(token);
232 extraData.Add(new (std::nothrow) String(key), new (std::nothrow) String(value));
235 //Adding this explicitly as there no other way to invoke call from webapp
236 extraData.Add(new (std::nothrow) String(PARAM_CALL_TYPE), new (std::nothrow) String(PARAM_CALL_VALUE_VOICE));
238 ProcessAppControlRequest(reqId,operationId,&extraData);
240 extraData.RemoveAll(true);
244 CallApp::ProcessAppControlRequest(RequestId reqId, const String& operationId,const IMap* pArgsMap,const String* pUriData)
246 AppLogDebug("Enter %ls",operationId.GetPointer());
247 __pLaunchArgs = null;
248 if(operationId.Equals(OPERATION_ID_CALL,true) == true)
250 AppLogDebug("OPERATION_ID_CALL");
253 bool isIncomingCallRequest = false;
254 String* pKey = new (std::nothrow) String(LAUNCHTYPE);
255 if (pArgsMap->ContainsKey(*pKey) == true)
257 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
258 if ((pValue != null) && (pValue->Equals(PARAM_ORIGIN_MT, true) == true))
260 isIncomingCallRequest = true;
263 //Check if incoming call request or outgoing call request
264 if(isIncomingCallRequest == true)
266 HandleIncomingCallAppControlRequest(reqId, pArgsMap);
270 HandleDialCallAppControlRequest(reqId, pArgsMap,pUriData);
275 AppLogDebug("pArgsMap == null");
281 CallApp::HandleIncomingCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
283 AppLogDebug("Enter");
284 SceneManager* pSceneManager = SceneManager::GetInstance();
286 AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
289 String callHandle(L"");
290 String* pKey = new (std::nothrow) String(CALL_HANDLE);
291 if (pArgsMap->ContainsKey(*pKey) == true)
293 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
296 callHandle.Append(*pValue);
301 String contactNumber(L"");
302 pKey = new (std::nothrow) String(CONTACT_NUMBER);
303 if (pArgsMap->ContainsKey(*pKey) == true)
305 const String* pContactValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
306 if (pContactValue != null)
308 contactNumber.Append(*pContactValue);
309 AppLogDebug("%ls",contactNumber.GetPointer());
315 //Fetch incoming call details
316 CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
317 AppCallInfo* pIncomingCall = pCallPresentor->FetchIncomingCallDetailsN(callHandle, contactNumber);
318 if(pIncomingCall != null)
320 bool isCallRejected = pCallPresentor->CheckIncomingCallToBeRejected(pIncomingCall);
321 if(isCallRejected == false)
323 //Abort any AppControl Request running already to show incoming call screen
324 if (pCallPresentor->IsAppControlRunning() == true)
326 pCallPresentor->AbortAppControlRequest();
328 //save app launch argument list
329 __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
330 __pLaunchArgs->Construct(1);
331 __pLaunchArgs->Add(pIncomingCall);
332 if(__initialSceneId.IsEmpty() == true)
334 __initialSceneId = IDSCN_SCENE_INCOMINGCALL;
338 //App already initialized, goto incoming call form
339 pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL), __pLaunchArgs);
340 __pLaunchArgs = null;
345 //Show messageBox showing automatic call rejection
346 /*MessageBox callRejectedInoMsgBox;
347 String msg(L"Call From ");
348 msg.Append(contactNumber);
349 msg.Append(L" Rejected.");
350 callRejectedInoMsgBox.Construct(L"Call Rejected", msg, MSGBOX_STYLE_NONE,1000);
352 // Calls ShowAndWait() : Draws and Shows itself and processes events
353 callRejectedInoMsgBox.ShowAndWait(modalResult);*/
355 //go back to previous scene if App was already running, else exit application.
356 if(__initialSceneId.IsEmpty() == true)
358 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
359 AppLog("Terminate Phone Application");
363 //set success message
364 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
368 appControlResult = APP_CTRL_RESULT_FAILED;
370 AppLogDebug("Exiting %d",appControlResult);
371 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
375 CallApp::HandleDialCallAppControlRequest(RequestId reqId,const IMap* pArgsMap,const String* pUriData)
378 AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
380 if (pArgsMap != null)
382 String callType(L"");
383 String phoneNumber(L"");
385 String* pKey = new (std::nothrow) String(PARAM_PHONE_NUMBER);
386 if(pArgsMap->ContainsKey(*pKey) == true)
388 const String* pPhoneValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
389 if(pPhoneValue != null)
391 AppLogDebug("%ls",pPhoneValue->GetPointer());
392 phoneNumber.Append(*pPhoneValue);
397 AppLogDebug("PARAM_PHONE_NUMBER not present");
398 //Now check if tel uri is present
401 AppLogDebug("pUriData is present %ls",pUriData->GetPointer());
402 phoneNumber.Append(*pUriData);
403 if(phoneNumber.Contains(PARAM_PHONE_NUMBER))
405 phoneNumber.Replace(PARAM_PHONE_NUMBER,L"");
406 if(phoneNumber.Contains(DELIMITER))
408 phoneNumber.Replace(DELIMITER,L"");
409 AppLogDebug("%ls",phoneNumber.GetPointer());
412 AppLogDebug("%ls",phoneNumber.GetPointer());
416 //Check if its a valid number
417 if(CheckNumberIsValid(phoneNumber) == false)
419 //go back to previous scene if App was already running, else exit application.
420 if(__initialSceneId.IsEmpty() == true)
422 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
423 AppLog("Terminate Phone Application");
424 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
430 //invalid phone number.always return, but App will come to foreground
431 //and show current screen, if any calls is present.
436 pKey = new (std::nothrow) String(PARAM_CALL_TYPE);
437 if(pArgsMap->ContainsKey(*pKey) == true)
439 const String* pCallTypeValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
440 if(pCallTypeValue != null)
442 callType.Append(*pCallTypeValue);
448 //Fetch currently active call count
449 if (callType.IsEmpty() == false
450 && callType.Equals(PARAM_CALL_VALUE_VOICE, false) == true
451 && phoneNumber.IsEmpty() == false)
453 SceneManager* pSceneManager = SceneManager::GetInstance();
454 //check if there is already a call in dialing mode, then dont accept any other dialing request.
455 if (pSceneManager->GetCurrentSceneId() == IDSCN_SCENE_OUTCALL
456 || pSceneManager->GetCurrentSceneId()
457 == IDSCN_SCENE_OUT_EMERGENCYCALL)
460 appControlResult = APP_CTRL_RESULT_CANCELED;
461 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
464 CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
465 int currentActiveCallCount = pCallPresentor->GetCurrentCallCount();
466 if(currentActiveCallCount <= 1)
468 //Abort any AppControl Request running already to show incoming call screen
469 if (pCallPresentor->IsAppControlRunning() == true)
471 pCallPresentor->AbortAppControlRequest();
473 //make an outgoing call with given number
474 String* contactTxt = new (std::nothrow) String(phoneNumber);
475 __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
476 __pLaunchArgs->Construct();
477 __pLaunchArgs->Add(contactTxt);
478 bool isEmergencyCall = pCallPresentor->IsEmergencyNumber(*contactTxt, true);
480 SceneId nextScene = IDSCN_SCENE_OUTCALL;
483 nextScene = IDSCN_SCENE_OUT_EMERGENCYCALL;
485 //Check if app was already running
486 if(__initialSceneId.IsEmpty() == true)
488 //phone App is not already launched
489 __initialSceneId = nextScene;
493 AppLog("Outgoing call");
494 pSceneManager->GoForward( ForwardSceneTransition( nextScene), __pLaunchArgs);
496 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
500 //already 2 active calls, 3rd call not allowed
501 appControlResult = APP_CTRL_RESULT_CANCELED;
506 appControlResult = APP_CTRL_RESULT_FAILED;
509 //send response message
510 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
514 CallApp::CheckNumberIsValid(String phoneNumber)
516 //Pattern to compare all characters except 0-9 * # P ; , +
517 String phoneNumberPattern(L"[^0-9*#P,p+;]");
518 String phoneNumberEndingWithHash(L"#$");
519 RegularExpression checkPhoneNumber,checkHash;
520 checkPhoneNumber.Construct(phoneNumberPattern);
521 checkHash.Construct(phoneNumberEndingWithHash);
522 //If there is any character other than these listed above then display invalid number
523 bool resultMatch = checkPhoneNumber.Match(phoneNumber,false);
524 //return false for patterns other than 0-9 * # P ; , +
525 bool endsWithHash = checkHash.Match(phoneNumber,false);
526 //returns false for any numbers that end with Hash
527 if(resultMatch == true || endsWithHash == true)
529 //return phone number is invalid
538 CallApp::SetTopMostWindow(bool bTopMost)
540 AppLogDebug("bTopMost = %d",bTopMost);
541 result res = E_FAILURE;
542 //ToDO: Need to see if there is better way to handle
547 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_HIGHEST);
548 AppManager::GetInstance()->AddActiveAppEventListener(*this);
549 if(PowerManager::IsScreenOn() == false)
551 AppLogDebug("TurnScreenOn");
552 res = PowerManager::TurnScreenOn();
553 AppLogDebug("TurnScreenOn %d",res);
559 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_NORMAL);
560 PowerManager::KeepScreenOnState(false);
561 AppManager::GetInstance()->RemoveActiveAppEventListener(*this);
564 if(LockManager::GetInstance()->IsLocked())
566 AppLogDebug("Phone Locked");
567 LockManager::GetInstance()->Unlock();
572 CallApp::OnActiveAppChanged(const String& appId)
574 AppLogDebug("Enter %ls",appId.GetPointer());
575 if(GetAppId().Equals(appId) == true)
577 result res = PowerManager::KeepScreenOnState(true,false);
578 AppLogDebug("KeepScreenOnState %d",res);