+//
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Flora License, Version 1.1 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://floralicense.org/license/
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an AS IS BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
/**
* Name : CallApp
* Version :
*/
#include <FUi.h>
+#include <FShell.h>
#include "CallApp.h"
#include "CallAppFrame.h"
#include "CallPresentationModel.h"
using namespace Tizen::Base::Utility;
using namespace Tizen::Base::Collection;
using namespace Tizen::Base::Utility;
+using namespace Tizen::Shell;
CallApp::CallApp(void):__initialSceneId(L""), __pLaunchArgs(null)
{
AppControlProviderManager* pProviderMgr = AppControlProviderManager::GetInstance();
pProviderMgr->SetAppControlProviderEventListener(this);
+ PowerManager::AddScreenEventListener(*this);
return true;
}
// TODO:
// Deallocate resources allocated by this App for termination.
// The App's permanent data and context can be saved via appRegistry.
+ PowerManager::RemoveScreenEventListener(*this);
return true;
}
void
CallApp::OnScreenOff(void)
{
- // TODO:
- // Unless there is a strong reason to do otherwise, release resources (such as 3D, media, and sensors) to allow the device
- // to enter the sleep mode to save the battery.
- // Invoking a lengthy asynchronous method within this listener method can be risky, because it is not guaranteed to invoke a
- // callback before the device enters the sleep mode.
- // Similarly, do not perform lengthy operations in this listener method. Any operation must be a quick one.
+ AppLogDebug("Enter");
+ IEnumerator* pEnum = __listenerList.GetEnumeratorN();
+ while (pEnum->MoveNext() == E_SUCCESS)
+ {
+ IAppStateChangeListener* pInterface = static_cast<IAppStateChangeListener*>(pEnum->GetCurrent());
+ if (pInterface == null)
+ {
+ delete pEnum;
+
+ return;
+ }
+ pInterface->OnScreenOff();
+ }
+ delete pEnum;
+
}
SceneId
CallApp::OnAppControlRequestReceived(RequestId reqId, const String& operationId, const String* pUriData,
const String* pMimeType, const IMap* pExtraData)
{
- AppLogDebug("ENTER");
- //process AppControl parameters
- ProcessAppControlRequest(reqId, operationId, pExtraData);
+ AppLogDebug("Enter ");
+ if(pUriData != null)
+ {
+ AppLogDebug("%ls ",pUriData->GetPointer());
+ }
+
+ if(pExtraData == null && pUriData != null)
+ {
+ //The request is from web app
+ AppLogDebug("%ls",pUriData->GetPointer());
+ ProcessWebAppControlRequest(reqId, operationId, pUriData);
+ }
+ else
+ {
+ //process AppControl parameters
+ ProcessAppControlRequest(reqId, operationId, pExtraData,pUriData);
+ }
AppLogDebug("EXIT");
}
void
-CallApp::ProcessAppControlRequest(RequestId reqId, const String& operationId,const IMap* pArgsMap)
+CallApp::ProcessWebAppControlRequest(RequestId reqId, const String& operationId,const String* pUriData)
+{
+ //Construct map from string
+ String delim(DELIMITER);
+ StringTokenizer st(*pUriData,delim);
+ String token;
+ HashMap extraData;
+ extraData.Construct();
+ while(st.HasMoreTokens())
+ {
+ String key=L"";
+ String value=L"";
+ st.GetNextToken(token);
+ token.Trim();
+ key.Append(token);
+ if(st.HasMoreTokens())
+ {
+ token.Clear();
+ st.GetNextToken(token);
+ token.Trim();
+ value.Append(token);
+ }
+ extraData.Add(new (std::nothrow) String(key), new (std::nothrow) String(value));
+ }
+
+ //Adding this explicitly as there no other way to invoke call from webapp
+ extraData.Add(new (std::nothrow) String(PARAM_CALL_TYPE), new (std::nothrow) String(PARAM_CALL_VALUE_VOICE));
+
+ ProcessAppControlRequest(reqId,operationId,&extraData);
+
+ extraData.RemoveAll(true);
+}
+
+void
+CallApp::ProcessAppControlRequest(RequestId reqId, const String& operationId,const IMap* pArgsMap,const String* pUriData)
{
AppLogDebug("Enter %ls",operationId.GetPointer());
__pLaunchArgs = null;
}
else
{
- HandleDialCallAppControlRequest(reqId, pArgsMap);
+ HandleDialCallAppControlRequest(reqId, pArgsMap,pUriData);
}
}
else
//Fetch incoming call details
CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
- CallInfo* pIncomingCall = pCallPresentor->FetchIncomingCallDetailsN(callHandle, contactNumber);
+ //Check if there is already a dial call present .This can happen in some
+ //race conditions N_SE-39531
+ if(pCallPresentor->IsIncomingorDialingCallPresent())
+ {
+ int incomingHandle;
+ Integer::Parse(callHandle,incomingHandle);
+ pCallPresentor->RejectCall(incomingHandle,false,contactNumber);
+ AppLog("Cancelled already an incoming call present");
+ appControlResult = APP_CTRL_RESULT_CANCELED;
+ AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
+ return;
+ }
+
+ AppCallInfo* pIncomingCall = pCallPresentor->FetchIncomingCallDetailsN(callHandle, contactNumber);
if(pIncomingCall != null)
{
bool isCallRejected = pCallPresentor->CheckIncomingCallToBeRejected(pIncomingCall);
else
{
//App already initialized, goto incoming call form
- pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL), __pLaunchArgs);
+ pSceneManager->GoForward(ForwardSceneTransition(IDSCN_SCENE_INCOMINGCALL, SCENE_TRANSITION_ANIMATION_TYPE_NONE,
+ SCENE_HISTORY_OPTION_NO_HISTORY, SCENE_DESTROY_OPTION_KEEP), __pLaunchArgs);
__pLaunchArgs = null;
}
+
+
}
else
{
//Show messageBox showing automatic call rejection
- MessageBox callRejectedInoMsgBox;
+ /*MessageBox callRejectedInoMsgBox;
String msg(L"Call From ");
msg.Append(contactNumber);
msg.Append(L" Rejected.");
callRejectedInoMsgBox.Construct(L"Call Rejected", msg, MSGBOX_STYLE_NONE,1000);
int modalResult = 0;
// Calls ShowAndWait() : Draws and Shows itself and processes events
- callRejectedInoMsgBox.ShowAndWait(modalResult);
+ callRejectedInoMsgBox.ShowAndWait(modalResult);*/
//go back to previous scene if App was already running, else exit application.
if(__initialSceneId.IsEmpty() == true)
AppLog("Terminate Phone Application");
Terminate();
}
-
}
//set success message
appControlResult = APP_CTRL_RESULT_SUCCEEDED;
}
void
-CallApp::HandleDialCallAppControlRequest(RequestId reqId,const IMap* pArgsMap)
+CallApp::HandleDialCallAppControlRequest(RequestId reqId,const IMap* pArgsMap,const String* pUriData)
{
//response message
AppCtrlResult appControlResult = APP_CTRL_RESULT_FAILED;
else
{
AppLogDebug("PARAM_PHONE_NUMBER not present");
+ //Now check if tel uri is present
+ if(pUriData != null)
+ {
+ AppLogDebug("pUriData is present %ls",pUriData->GetPointer());
+ phoneNumber.Append(*pUriData);
+ if(phoneNumber.Contains(PARAM_PHONE_NUMBER))
+ {
+ phoneNumber.Replace(PARAM_PHONE_NUMBER,L"");
+ if(phoneNumber.Contains(DELIMITER))
+ {
+ phoneNumber.Replace(DELIMITER,L"");
+ AppLogDebug("%ls",phoneNumber.GetPointer());
+ }
+ }
+ AppLogDebug("%ls",phoneNumber.GetPointer());
+ }
}
delete pKey;
//Check if its a valid number
if(CheckNumberIsValid(phoneNumber) == false)
{
- //Show messageBox showing automatic call rejection
- MessageBox InvalidNumberMsgBox;
- InvalidNumberMsgBox.Construct(AppUtility::GetResourceString(IDS_INVALID_NUMBER), L"",MSGBOX_STYLE_NONE,1000);
- int modalResult = 0;
- // Calls ShowAndWait() : Draws and Shows itself and processes events
- InvalidNumberMsgBox.ShowAndWait(modalResult);
-
//go back to previous scene if App was already running, else exit application.
if(__initialSceneId.IsEmpty() == true)
{
//KEEP "__initialSceneId" as empty and return false from "OnAppInitialized()"
AppLog("Terminate Phone Application");
+ AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
Terminate();
+ return;
+ }
+ else
+ {
+ //invalid phone number.always return, but App will come to foreground
+ //and show current screen, if any calls is present.
+ return;
}
-
}
//call type
pKey = new (std::nothrow) String(PARAM_CALL_TYPE);
AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
return;
}
+
CallPresentationModel* pCallPresentor = CallPresentationModel::GetInstance();
+ //Check if there is already an incoming call
+ //this can happen in some race conditions N_SE-39531
+ if(pCallPresentor->IsIncomingorDialingCallPresent() == true)
+ {
+ AppLog("Cancelled already an incoming call present");
+ appControlResult = APP_CTRL_RESULT_CANCELED;
+ AppControlProviderManager::GetInstance()->SendAppControlResult(reqId, appControlResult, null);
+ return;
+ }
int currentActiveCallCount = pCallPresentor->GetCurrentCallCount();
if(currentActiveCallCount <= 1)
{
+ //Abort any AppControl Request running already to show incoming call screen
+ if (pCallPresentor->IsAppControlRunning() == true)
+ {
+ pCallPresentor->AbortAppControlRequest();
+ }
//make an outgoing call with given number
String* contactTxt = new (std::nothrow) String(phoneNumber);
__pLaunchArgs = new (std::nothrow) ArrayList(SingleObjectDeleter);
}
else
{
- pSceneManager->GoForward( ForwardSceneTransition( nextScene), __pLaunchArgs);
+ AppLog("Outgoing call");
+ pSceneManager->GoForward( ForwardSceneTransition( nextScene, SCENE_TRANSITION_ANIMATION_TYPE_NONE,
+ SCENE_HISTORY_OPTION_NO_HISTORY, SCENE_DESTROY_OPTION_KEEP), __pLaunchArgs);
}
appControlResult = APP_CTRL_RESULT_SUCCEEDED;
}
CallApp::CheckNumberIsValid(String phoneNumber)
{
//Pattern to compare all characters except 0-9 * # P ; , +
- String phoneNumberPattern(L"[^0-9*#P;,+]");
+ String phoneNumberPattern(L"[^0-9*#P,p+;]");
RegularExpression checkPhoneNumber;
checkPhoneNumber.Construct(phoneNumberPattern);
//If there is any character other than these listed above then display invalid number
bool resultMatch = checkPhoneNumber.Match(phoneNumber,false);
//return false for patterns other than 0-9 * # P ; , +
- return !resultMatch;
+ if(resultMatch == true)
+ {
+ //return phone number is invalid
+ return false;
+ }
+
+ return true;
+
+}
+
+void
+CallApp::SetTopMostWindow(bool bTopMost)
+{
+ AppLogDebug("bTopMost = %d",bTopMost);
+ result res = E_FAILURE;
+ //ToDO: Need to see if there is better way to handle
+ //this case
+
+ if(bTopMost == true)
+ {
+ GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_HIGHEST);
+ AppManager::GetInstance()->AddActiveAppEventListener(*this);
+ /*if(PowerManager::IsScreenOn() == false)
+ {
+ AppLogDebug("TurnScreenOn");
+ res = PowerManager::TurnScreenOn();
+ AppLogDebug("TurnScreenOn %d",res);
+ }*/
+
+ }
+ else
+ {
+ GetAppFrame()->GetFrame()->SetZOrderGroup(WINDOW_Z_ORDER_GROUP_NORMAL);
+ PowerManager::KeepScreenOnState(false);
+ AppManager::GetInstance()->RemoveActiveAppEventListener(*this);
+ }
+
+ if(LockManager::GetInstance()->IsLocked())
+ {
+ AppLogDebug("Phone Locked");
+ LockManager::GetInstance()->Unlock();
+ }
+
+}
+void
+CallApp::OnActiveAppChanged(const String& appId)
+{
+ AppLogDebug("Enter %ls",appId.GetPointer());
+ if(GetAppId().Equals(appId) == true)
+ {
+ result res = PowerManager::KeepScreenOnState(true,false);
+ AppLogDebug("KeepScreenOnState %d",res);
+
+ }
}