2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.1 (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
8 // http://floralicense.org/license/
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.
26 #include "CallAppFrame.h"
27 #include "CallPresentationModel.h"
28 #include "CallTypes.h"
29 #include "CallAppUtility.h"
30 #include "CallIAppStateChangeListner.h"
32 using namespace Tizen::App;
33 using namespace Tizen::Base;
34 using namespace Tizen::System;
35 using namespace Tizen::Ui;
36 using namespace Tizen::Ui::Controls;
37 using namespace Tizen::Ui::Scenes;
38 using namespace Tizen::Base::Utility;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::Base::Utility;
41 using namespace Tizen::Shell;
44 CallApp::CallApp(void):__initialSceneId(L""), __pLaunchArgs(null)
46 __listenerList.Construct();
49 CallApp::~CallApp(void)
54 CallApp::CreateInstance(void)
56 // Create the instance through the constructor.
61 CallApp::OnAppInitializing(AppRegistry& appRegistry)
63 AppControlProviderManager* pProviderMgr = AppControlProviderManager::GetInstance();
64 pProviderMgr->SetAppControlProviderEventListener(this);
65 PowerManager::AddScreenEventListener(*this);
70 CallApp::OnAppInitialized(void)
76 CallAppFrame* pCallAppFrame = new CallAppFrame();
77 pCallAppFrame->Construct();
78 pCallAppFrame->SetName(L"CallApp");
79 AddFrame(*pCallAppFrame);
81 //Check if there is no initial scene, then exit application.
82 //This case will normally come when invalid AppControl request has come,
83 //or incoming call is coming from unknown number and "reject unknown number" settings is enabled.
84 if (GetInitialScene().IsEmpty() == true)
93 CallApp::OnAppWillTerminate(void)
101 CallApp::OnAppTerminating(AppRegistry& appRegistry, bool forcedTermination)
104 // Deallocate resources allocated by this App for termination.
105 // The App's permanent data and context can be saved via appRegistry.
106 PowerManager::RemoveScreenEventListener(*this);
111 CallApp::OnForeground(void)
113 IEnumerator* pEnum = __listenerList.GetEnumeratorN();
114 while (pEnum->MoveNext() == E_SUCCESS)
116 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
117 if (pInterface == null)
123 pInterface->OnForeground();
129 CallApp::OnBackground(void)
132 // Stop drawing when the application is moved to the background.
136 CallApp::OnLowMemory(void)
139 // Free unused resources or close the application.
143 CallApp::OnBatteryLevelChanged(BatteryLevel batteryLevel)
146 // Handle any changes in battery level here.
147 // Stop using multimedia features(camera, mp3 etc.) if the battery level is CRITICAL.
151 CallApp::OnScreenOn(void)
154 // Get the released resources or resume the operations that were paused or stopped in OnScreenOff().
158 CallApp::OnScreenOff(void)
160 AppLogDebug("Enter");
161 IEnumerator* pEnum = __listenerList.GetEnumeratorN();
162 while (pEnum->MoveNext() == E_SUCCESS)
164 IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
165 if (pInterface == null)
171 pInterface->OnScreenOff();
178 CallApp::GetInitialScene(void)
180 return __initialSceneId;
184 CallApp::GetAppLaunchArguments(void)
186 return __pLaunchArgs;
190 CallApp::AddAppStateChangeListener(const IAppStateChangeListener& listener)
192 __listenerList.Add(listener);
196 CallApp::RemoveAppStateChangeListener(const IAppStateChangeListener& listener)
198 __listenerList.Remove(listener);
202 CallApp::OnAppControlRequestReceived(RequestId reqId, const String& operationId, const String* pUriData,
203 const String* pMimeType, const IMap* pExtraData)
205 AppLogDebug("Enter ");
208 AppLogDebug("%ls ",pUriData->GetPointer());
211 if(pExtraData == null && pUriData != null)
213 //The request is from web app
214 AppLogDebug("%ls",pUriData->GetPointer());
215 ProcessWebAppControlRequest(reqId, operationId, pUriData);
219 //process AppControl parameters
220 ProcessAppControlRequest(reqId, operationId, pExtraData,pUriData);
226 CallApp::ProcessWebAppControlRequest(RequestId reqId, const String& operationId,const String* pUriData)
228 //Construct map from string
229 String delim(DELIMITER);
230 StringTokenizer st(*pUriData,delim);
233 extraData.Construct();
234 while(st.HasMoreTokens())
238 st.GetNextToken(token);
241 if(st.HasMoreTokens())
244 st.GetNextToken(token);
248 extraData.Add(new (std::nothrow) String(key), new (std::nothrow) String(value));
251 //Adding this explicitly as there no other way to invoke call from webapp
252 extraData.Add(new (std::nothrow) String(PARAM_CALL_TYPE), new (std::nothrow) String(PARAM_CALL_VALUE_VOICE));
254 ProcessAppControlRequest(reqId,operationId,&extraData);
256 extraData.RemoveAll(true);
260 CallApp::ProcessAppControlRequest(RequestId reqId, const String& operationId,const IMap* pArgsMap,const String* pUriData)
262 AppLogDebug("Enter %ls",operationId.GetPointer());
263 __pLaunchArgs = null;
264 if(operationId.Equals(OPERATION_ID_CALL,true) == true)
266 AppLogDebug("OPERATION_ID_CALL");
269 bool isIncomingCallRequest = false;
270 String* pKey = new (std::nothrow) String(LAUNCHTYPE);
271 if (pArgsMap->ContainsKey(*pKey) == true)
273 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
274 if ((pValue != null) && (pValue->Equals(PARAM_ORIGIN_MT, true) == true))
276 isIncomingCallRequest = true;
279 //Check if incoming call request or outgoing call request
280 if(isIncomingCallRequest == true)
282 HandleIncomingCallAppControlRequest(reqId, pArgsMap);
286 HandleDialCallAppControlRequest(reqId, pArgsMap,pUriData);
291 AppLogDebug("pArgsMap == null");
297 CallApp::HandleIncomingCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
299 AppLogDebug("Enter");
300 SceneManager* pSceneManager = SceneManager::GetInstance();
302 AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
305 String callHandle(L"");
306 String* pKey = new (std::nothrow) String(CALL_HANDLE);
307 if (pArgsMap->ContainsKey(*pKey) == true)
309 const String* pValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
312 callHandle.Append(*pValue);
317 String contactNumber(L"");
318 pKey = new (std::nothrow) String(CONTACT_NUMBER);
319 if (pArgsMap->ContainsKey(*pKey) == true)
321 const String* pContactValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
322 if (pContactValue != null)
324 contactNumber.Append(*pContactValue);
325 AppLogDebug("%ls",contactNumber.GetPointer());
331 //Fetch incoming call details
332 CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
333 AppCallInfo* pIncomingCall = pCallPresentor->FetchIncomingCallDetailsN(callHandle, contactNumber);
334 if(pIncomingCall != null)
336 bool isCallRejected = pCallPresentor->CheckIncomingCallToBeRejected(pIncomingCall);
337 if(isCallRejected == false)
339 //Abort any AppControl Request running already to show incoming call screen
340 if (pCallPresentor->IsAppControlRunning() == true)
342 pCallPresentor->AbortAppControlRequest();
344 //save app launch argument list
345 __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
346 __pLaunchArgs->Construct(1);
347 __pLaunchArgs->Add(pIncomingCall);
348 if(__initialSceneId.IsEmpty() == true)
350 __initialSceneId = IDSCN_SCENE_INCOMINGCALL;
354 //App already initialized, goto incoming call form
355 pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL), __pLaunchArgs);
356 __pLaunchArgs = null;
361 //Show messageBox showing automatic call rejection
362 /*MessageBox callRejectedInoMsgBox;
363 String msg(L"Call From ");
364 msg.Append(contactNumber);
365 msg.Append(L" Rejected.");
366 callRejectedInoMsgBox.Construct(L"Call Rejected", msg, MSGBOX_STYLE_NONE,1000);
368 // Calls ShowAndWait() : Draws and Shows itself and processes events
369 callRejectedInoMsgBox.ShowAndWait(modalResult);*/
371 //go back to previous scene if App was already running, else exit application.
372 if(__initialSceneId.IsEmpty() == true)
374 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
375 AppLog("Terminate Phone Application");
379 //set success message
380 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
384 appControlResult = APP_CTRL_RESULT_FAILED;
386 AppLogDebug("Exiting %d",appControlResult);
387 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
391 CallApp::HandleDialCallAppControlRequest(RequestId reqId,const IMap* pArgsMap,const String* pUriData)
394 AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
396 if (pArgsMap != null)
398 String callType(L"");
399 String phoneNumber(L"");
401 String* pKey = new (std::nothrow) String(PARAM_PHONE_NUMBER);
402 if(pArgsMap->ContainsKey(*pKey) == true)
404 const String* pPhoneValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
405 if(pPhoneValue != null)
407 AppLogDebug("%ls",pPhoneValue->GetPointer());
408 phoneNumber.Append(*pPhoneValue);
413 AppLogDebug("PARAM_PHONE_NUMBER not present");
414 //Now check if tel uri is present
417 AppLogDebug("pUriData is present %ls",pUriData->GetPointer());
418 phoneNumber.Append(*pUriData);
419 if(phoneNumber.Contains(PARAM_PHONE_NUMBER))
421 phoneNumber.Replace(PARAM_PHONE_NUMBER,L"");
422 if(phoneNumber.Contains(DELIMITER))
424 phoneNumber.Replace(DELIMITER,L"");
425 AppLogDebug("%ls",phoneNumber.GetPointer());
428 AppLogDebug("%ls",phoneNumber.GetPointer());
432 //Check if its a valid number
433 if(CheckNumberIsValid(phoneNumber) == false)
435 //go back to previous scene if App was already running, else exit application.
436 if(__initialSceneId.IsEmpty() == true)
438 //KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
439 AppLog("Terminate Phone Application");
440 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
446 //invalid phone number.always return, but App will come to foreground
447 //and show current screen, if any calls is present.
452 pKey = new (std::nothrow) String(PARAM_CALL_TYPE);
453 if(pArgsMap->ContainsKey(*pKey) == true)
455 const String* pCallTypeValue = static_cast<const String*>(pArgsMap->GetValue(*pKey));
456 if(pCallTypeValue != null)
458 callType.Append(*pCallTypeValue);
464 //Fetch currently active call count
465 if (callType.IsEmpty() == false
466 && callType.Equals(PARAM_CALL_VALUE_VOICE, false) == true
467 && phoneNumber.IsEmpty() == false)
469 SceneManager* pSceneManager = SceneManager::GetInstance();
470 //check if there is already a call in dialing mode, then dont accept any other dialing request.
471 if (pSceneManager->GetCurrentSceneId() == IDSCN_SCENE_OUTCALL
472 || pSceneManager->GetCurrentSceneId()
473 == IDSCN_SCENE_OUT_EMERGENCYCALL)
476 appControlResult = APP_CTRL_RESULT_CANCELED;
477 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
480 CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
481 int currentActiveCallCount = pCallPresentor->GetCurrentCallCount();
482 if(currentActiveCallCount <= 1)
484 //Abort any AppControl Request running already to show incoming call screen
485 if (pCallPresentor->IsAppControlRunning() == true)
487 pCallPresentor->AbortAppControlRequest();
489 //make an outgoing call with given number
490 String* contactTxt = new (std::nothrow) String(phoneNumber);
491 __pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
492 __pLaunchArgs->Construct();
493 __pLaunchArgs->Add(contactTxt);
494 bool isEmergencyCall = pCallPresentor->IsEmergencyNumber(*contactTxt, true);
496 SceneId nextScene = IDSCN_SCENE_OUTCALL;
499 nextScene = IDSCN_SCENE_OUT_EMERGENCYCALL;
501 //Check if app was already running
502 if(__initialSceneId.IsEmpty() == true)
504 //phone App is not already launched
505 __initialSceneId = nextScene;
509 AppLog("Outgoing call");
510 pSceneManager->GoForward( ForwardSceneTransition( nextScene), __pLaunchArgs);
512 appControlResult = APP_CTRL_RESULT_SUCCEEDED;
516 //already 2 active calls, 3rd call not allowed
517 appControlResult = APP_CTRL_RESULT_CANCELED;
522 appControlResult = APP_CTRL_RESULT_FAILED;
525 //send response message
526 AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
530 CallApp::CheckNumberIsValid(String phoneNumber)
532 //Pattern to compare all characters except 0-9 * # P ; , +
533 String phoneNumberPattern(L"[^0-9*#P,p+;]");
534 RegularExpression checkPhoneNumber;
535 checkPhoneNumber.Construct(phoneNumberPattern);
536 //If there is any character other than these listed above then display invalid number
537 bool resultMatch = checkPhoneNumber.Match(phoneNumber,false);
538 //return false for patterns other than 0-9 * # P ; , +
539 if(resultMatch == true)
541 //return phone number is invalid
550 CallApp::SetTopMostWindow(bool bTopMost)
552 AppLogDebug("bTopMost = %d",bTopMost);
553 result res = E_FAILURE;
554 //ToDO: Need to see if there is better way to handle
559 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_HIGHEST);
560 AppManager::GetInstance()->AddActiveAppEventListener(*this);
561 if(PowerManager::IsScreenOn() == false)
563 AppLogDebug("TurnScreenOn");
564 res = PowerManager::TurnScreenOn();
565 AppLogDebug("TurnScreenOn %d",res);
571 GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_NORMAL);
572 PowerManager::KeepScreenOnState(false);
573 AppManager::GetInstance()->RemoveActiveAppEventListener(*this);
576 if(LockManager::GetInstance()->IsLocked())
578 AppLogDebug("Phone Locked");
579 LockManager::GetInstance()->Unlock();
584 CallApp::OnActiveAppChanged(const String& appId)
586 AppLogDebug("Enter %ls",appId.GetPointer());
587 if(GetAppId().Equals(appId) == true)
589 result res = PowerManager::KeepScreenOnState(true,false);
590 AppLogDebug("KeepScreenOnState %d",res);