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);
53 CallApp::OnAppInitialized(void)
59 CallAppFrame* pCallAppFrame = new CallAppFrame();
60 pCallAppFrame->Construct();
61 pCallAppFrame->SetName(L"CallApp");
62 AddFrame(*pCallAppFrame);
64 //Check if there is no initial scene, then exit application.
65 //This case will normally come when invalid AppControl request has come,
66 //or incoming call is coming from unknown number and "reject unknown number" settings is enabled.
67 if (GetInitialScene().IsEmpty() == true)
76 CallApp::OnAppWillTerminate(void)
84 CallApp::OnAppTerminating(AppRegistry& appRegistry, bool forcedTermination)
87 // Deallocate resources allocated by this App for termination.
88 // The App's permanent data and context can be saved via appRegistry.
93 CallApp::OnForeground(void)
95 IEnumerator* pEnum = __listenerList.GetEnumeratorN();
96 while (pEnum->MoveNext() == E_SUCCESS)
98 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
99 if (pInterface == null)
105 pInterface->OnForeground();
111 CallApp::OnBackground(void)
114 // Stop drawing when the application is moved to the background.
118 CallApp::OnLowMemory(void)
121 // Free unused resources or close the application.
125 CallApp::OnBatteryLevelChanged(BatteryLevel batteryLevel)
128 // Handle any changes in battery level here.
129 // Stop using multimedia features(camera, mp3 etc.) if the battery level is CRITICAL.
133 CallApp::OnScreenOn(void)
136 // Get the released resources or resume the operations that were paused or stopped in OnScreenOff().
140 CallApp::OnScreenOff(void)
143 // Unless there is a strong reason to do otherwise, release resources (such as 3D, media, and sensors) to allow the device
144 // to enter the sleep mode to save the battery.
145 // Invoking a lengthy asynchronous method within this listener method can be risky, because it is not guaranteed to invoke a
146 // callback before the device enters the sleep mode.
147 // Similarly, do not perform lengthy operations in this listener method. Any operation must be a quick one.
151 CallApp::GetInitialScene(void)
153 return __initialSceneId;
157 CallApp::GetAppLaunchArguments(void)
159 return __pLaunchArgs;
163 CallApp::AddAppStateChangeListener(const IAppStateChangeListener& listener)
165 __listenerList.Add(listener);
169 CallApp::RemoveAppStateChangeListener(const IAppStateChangeListener& listener)
171 __listenerList.Remove(listener);
175 CallApp::OnAppControlRequestReceived(RequestId reqId, const String& operationId, const String* pUriData,
176 const String* pMimeType, const IMap* pExtraData)
178 AppLogDebug("Enter ");
181 AppLogDebug("%ls ",pUriData->GetPointer());
184 if(pExtraData == null && pUriData != null)
186 //The request is from web app
187 AppLogDebug("%ls",pUriData->GetPointer());
188 ProcessWebAppControlRequest(reqId, operationId, pUriData);
192 //process AppControl parameters
193 ProcessAppControlRequest(reqId, operationId, pExtraData,pUriData);
199 CallApp::ProcessWebAppControlRequest(RequestId reqId, const String& operationId,const String* pUriData)
201 //Construct map from string
202 String delim(DELIMITER);
203 StringTokenizer st(*pUriData,delim);
206 extraData.Construct();
207 while(st.HasMoreTokens())
211 st.GetNextToken(token);
214 if(st.HasMoreTokens())
217 st.GetNextToken(token);
221 extraData.Add(new (std::nothrow) String(key), new (std::nothrow) String(value));
224 //Adding this explicitly as there no other way to invoke call from webapp
225 extraData.Add(new (std::nothrow) String(PARAM_CALL_TYPE), new (std::nothrow) String(PARAM_CALL_VALUE_VOICE));
227 ProcessAppControlRequest(reqId,operationId,&extraData);
229 extraData.RemoveAll(true);
233 CallApp::ProcessAppControlRequest(RequestId reqId, const String& operationId,const IMap* pArgsMap,const String* pUriData)
235 AppLogDebug("Enter %ls",operationId.GetPointer());
236 __pLaunchArgs = null;
237 if(operationId.Equals(OPERATION_ID_CALL,true) == true)
239 AppLogDebug("OPERATION_ID_CALL");
242 bool isIncomingCallRequest = false;
243 String* pKey = new (std::nothrow) String(LAUNCHTYPE);
244 if (pArgsMap->ContainsKey(*pKey) == true)
246 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
247 if ((pValue != null) && (pValue->Equals(PARAM_ORIGIN_MT, true) == true))
249 isIncomingCallRequest = true;
252 //Check if incoming call request or outgoing call request
253 if(isIncomingCallRequest == true)
255 HandleIncomingCallAppControlRequest(reqId, pArgsMap);
259 HandleDialCallAppControlRequest(reqId, pArgsMap,pUriData);
264 AppLogDebug("pArgsMap == null");
270 CallApp::HandleIncomingCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
272 AppLogDebug("Enter");
273 SceneManager* pSceneManager = SceneManager::GetInstance();
275 AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
278 String callHandle(L"");
279 String* pKey = new (std::nothrow) String(CALL_HANDLE);
280 if (pArgsMap->ContainsKey(*pKey) == true)
282 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
285 callHandle.Append(*pValue);
290 String contactNumber(L"");
291 pKey = new (std::nothrow) String(CONTACT_NUMBER);
292 if (pArgsMap->ContainsKey(*pKey) == true)
294 const String* pContactValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
295 if (pContactValue != null)
297 contactNumber.Append(*pContactValue);
298 AppLogDebug("%ls",contactNumber.GetPointer());
304 //Fetch incoming call details
305 CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
306 AppCallInfo* pIncomingCall = pCallPresentor->FetchIncomingCallDetailsN(callHandle, contactNumber);
307 if(pIncomingCall != null)
309 bool isCallRejected = pCallPresentor->CheckIncomingCallToBeRejected(pIncomingCall);
310 if(isCallRejected == false)
312 //Abort any AppControl Request running already to show incoming call screen
313 if (pCallPresentor->IsAppControlRunning() == true)
315 pCallPresentor->AbortAppControlRequest();
317 //save app launch argument list
318 __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
319 __pLaunchArgs->Construct(1);
320 __pLaunchArgs->Add(pIncomingCall);
321 if(__initialSceneId.IsEmpty() == true)
323 __initialSceneId = IDSCN_SCENE_INCOMINGCALL;
327 //App already initialized, goto incoming call form
328 pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL), __pLaunchArgs);
329 __pLaunchArgs = null;
334 //Show messageBox showing automatic call rejection
335 /*MessageBox callRejectedInoMsgBox;
336 String msg(L"Call From ");
337 msg.Append(contactNumber);
338 msg.Append(L" Rejected.");
339 callRejectedInoMsgBox.Construct(L"Call Rejected", msg, MSGBOX_STYLE_NONE,1000);
341 // Calls ShowAndWait() : Draws and Shows itself and processes events
342 callRejectedInoMsgBox.ShowAndWait(modalResult);*/
344 //go back to previous scene if App was already running, else exit application.
345 if(__initialSceneId.IsEmpty() == true)
347 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
348 AppLog("Terminate Phone Application");
352 //set success message
353 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
357 appControlResult = APP_CTRL_RESULT_FAILED;
359 AppLogDebug("Exiting %d",appControlResult);
360 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
364 CallApp::HandleDialCallAppControlRequest(RequestId reqId,const IMap* pArgsMap,const String* pUriData)
367 AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
369 if (pArgsMap != null)
371 String callType(L"");
372 String phoneNumber(L"");
374 String* pKey = new (std::nothrow) String(PARAM_PHONE_NUMBER);
375 if(pArgsMap->ContainsKey(*pKey) == true)
377 const String* pPhoneValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
378 if(pPhoneValue != null)
380 AppLogDebug("%ls",pPhoneValue->GetPointer());
381 phoneNumber.Append(*pPhoneValue);
386 AppLogDebug("PARAM_PHONE_NUMBER not present");
387 //Now check if tel uri is present
390 AppLogDebug("pUriData is present %ls",pUriData->GetPointer());
391 phoneNumber.Append(*pUriData);
392 if(phoneNumber.Contains(PARAM_PHONE_NUMBER))
394 phoneNumber.Replace(PARAM_PHONE_NUMBER,L"");
395 if(phoneNumber.Contains(DELIMITER))
397 phoneNumber.Replace(DELIMITER,L"");
398 AppLogDebug("%ls",phoneNumber.GetPointer());
401 AppLogDebug("%ls",phoneNumber.GetPointer());
405 //Check if its a valid number
406 if(CheckNumberIsValid(phoneNumber) == false)
408 //go back to previous scene if App was already running, else exit application.
409 if(__initialSceneId.IsEmpty() == true)
411 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
412 AppLog("Terminate Phone Application");
413 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
419 pKey = new (std::nothrow) String(PARAM_CALL_TYPE);
420 if(pArgsMap->ContainsKey(*pKey) == true)
422 const String* pCallTypeValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
423 if(pCallTypeValue != null)
425 callType.Append(*pCallTypeValue);
431 //Fetch currently active call count
432 if (callType.IsEmpty() == false
433 && callType.Equals(PARAM_CALL_VALUE_VOICE, false) == true
434 && phoneNumber.IsEmpty() == false)
436 SceneManager* pSceneManager = SceneManager::GetInstance();
437 //check if there is already a call in dialing mode, then dont accept any other dialing request.
438 if (pSceneManager->GetCurrentSceneId() == IDSCN_SCENE_OUTCALL
439 || pSceneManager->GetCurrentSceneId()
440 == IDSCN_SCENE_OUT_EMERGENCYCALL)
443 appControlResult = APP_CTRL_RESULT_CANCELED;
444 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
447 CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
448 int currentActiveCallCount = pCallPresentor->GetCurrentCallCount();
449 if(currentActiveCallCount <= 1)
451 //Abort any AppControl Request running already to show incoming call screen
452 if (pCallPresentor->IsAppControlRunning() == true)
454 pCallPresentor->AbortAppControlRequest();
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,p+;]");
501 String phoneNumberEndingWithHash(L"#$");
502 RegularExpression checkPhoneNumber,checkHash;
503 checkPhoneNumber.Construct(phoneNumberPattern);
504 checkHash.Construct(phoneNumberEndingWithHash);
505 //If there is any character other than these listed above then display invalid number
506 bool resultMatch = checkPhoneNumber.Match(phoneNumber,false);
507 //return false for patterns other than 0-9 * # P ; , +
508 bool endsWithHash = checkHash.Match(phoneNumber,false);
509 //returns false for any numbers that end with Hash
510 if(resultMatch == true || endsWithHash == true)
512 //return phone number is invalid
521 CallApp::SetTopMostWindow(bool bTopMost)
523 AppLogDebug("bTopMost = %d",bTopMost);
524 result res = E_FAILURE;
525 //ToDO: Need to see if there is better way to handle
530 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_HIGHEST);
531 if(PowerManager::IsScreenOn() == false)
533 AppLogDebug("TurnScreenOn");
534 res = PowerManager::TurnScreenOn();
535 AppLogDebug("TurnScreenOn %d",res);
537 AppManager::GetInstance()->AddActiveAppEventListener(*this);
542 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_NORMAL);
543 PowerManager::KeepScreenOnState(false);
544 AppManager::GetInstance()->RemoveActiveAppEventListener(*this);
546 //Unlock the phone if its locked
547 /* if(LockManager::GetInstance()->IsLocked())
549 AppLogDebug("Phone Locked");
550 LockManager::GetInstance()->Unlock();
555 CallApp::OnActiveAppChanged(const String& appId)
557 AppLogDebug("Enter %ls",appId.GetPointer());
558 if(GetAppId().Equals(appId) == true)
560 result res = PowerManager::KeepScreenOnState(true,false);
561 AppLogDebug("KeepScreenOnState %d",res);