/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qmlbackendmonitorao_s60_p.h"
#include "qgeoareamonitor_s60_p.h"
#include "qmlbackendmonitorinfo_s60_p.h"
#include "qmlbackendmonitorcreatetriggerao_s60_p.h"
QTM_BEGIN_NAMESPACE
//Sets the radius of the monitoring area, to aRadius.If the Radius is less than the MinimumTriggerAreaSize(),
//then aRadius will be set to MinimumTriggerAreaSize() supported by the LBT implementation.If the aRadius is
//greater than the MinimumTriggerAreaSize() it is unaltered.
TInt QMLBackendMonitorCreateTriggerAO::getRadius(qreal& aRadius)
{
TInt ret = KErrNone;
qreal minimumRadius;
TLbtTriggeringSystemSettings triggerSettings;
//gets the triggering System Setting
TRAP(ret, iLbt.GetTriggeringSystemSettingsL(triggerSettings));
if (ret != KErrNone)
return ret;
minimumRadius = triggerSettings.MinimumTriggerAreaSize();
if (aRadius < minimumRadius)
aRadius = minimumRadius;
return ret;
}
//creates a trigger of type aType(EntryTrigger/ExitTrigger), with the coordinates and radius as
//supplied in the argument
bool QMLBackendMonitorCreateTriggerAO::InitializeTrigger(QGeoAreaMonitorS60* aParent ,
enTriggerType aType,
TCoordinate& aCoordinate,
qreal& aRadius)
{
TInt ret = KErrGeneral;
TLbtTriggerId triggerID = NULL;
//try retrieving the trigger information from the linked list corresponding to the aParent and aType
CMonitorTriggerInfo* triggerInfo = iTriggerMonitorInfo->getMonitorTriggerInfo(aParent, aType);
//if no triggerinfo available in the linked list
if (triggerInfo == NULL) {
//Define the triggering area
CLbtGeoCircle* trigArea = NULL;
TRAP(ret, trigArea = CLbtGeoCircle::NewL(
aCoordinate ,//center coordinate
aRadius //radius in meters. If
//NaN is used, Location
//Triggering Server will
//use minimal size of trigger
//area as the radius of the
//trigger
));
if ((ret != KErrNone) || !trigArea)
return FALSE;
CleanupStack::PushL(trigArea);
CLbtTriggerConditionArea* cond = NULL;
if (aType == EntryTrigger) {
//2: Construct a entry type of trigger condition
TRAP(ret, cond = CLbtTriggerConditionArea::NewL(
trigArea,
CLbtTriggerConditionArea::EFireOnEnter
));
} else if (aType == ExitTrigger) {
TRAP(ret, cond = CLbtTriggerConditionArea::NewL(
trigArea,
CLbtTriggerConditionArea::EFireOnExit
));
}
if ((ret != KErrNone) || !cond) {
CleanupStack::PopAndDestroy(trigArea);
return FALSE;
}
CleanupStack::Pop(trigArea); //ownership of trigArea is transferred.
CleanupStack::PushL(cond);
RRequestorStack reqStack;
CleanupClosePushL(reqStack);
//trigger name.
_LIT(KMyTriggerName, "EntryTrigger");
TDesC triggerName(KMyTriggerName);
if (aType == ExitTrigger) {
_LIT(KMyTriggerName, "ExitTrigger");
triggerName = KMyTriggerName;
}
//Construct requestor
_LIT(KMyRequestorName, "QTLBTBackend"); //Application name used as requestor identifier
CRequestor *req = NULL;
TRAP(ret, req = CRequestor::NewL(
CRequestorBase::ERequestorService,
CRequestorBase::EFormatApplication,
KMyRequestorName
));
if ((ret != KErrNone) || !req) {
CleanupStack::PopAndDestroy(&reqStack);
CleanupStack::PopAndDestroy(cond);
return FALSE;
}
CleanupStack::PushL(req);
TRAP(ret, reqStack.AppendL(req));
CleanupStack::Pop(req);
if (ret != KErrNone) {
CleanupStack::PopAndDestroy(&reqStack);
CleanupStack::PopAndDestroy(cond);
return FALSE;
}
TUid managerUid = TUid::Uid(0);
CLbtSessionTrigger* trig = NULL;
TRAP(ret, trig = CLbtSessionTrigger::NewL(
triggerName,
CLbtTriggerEntry::EStateDisabled,
reqStack,
managerUid,
cond
));
CleanupStack::PopAndDestroy(&reqStack);
CleanupStack::Pop(cond);
trig->SetTimeToRearm(0);
if ((ret != KErrNone) || (!trig)) {
CleanupStack::PopAndDestroy(cond);
return FALSE;
}
CleanupStack::PushL(trig);
//iLbt.CreateTrigger(*trig, triggerID, ETrue, iStatus);
//CleanupStack::PopAndDestroy(trig );
TRAP(ret, iActiveSchedulerwait = new(ELeave) CActiveSchedulerWait);
if ((ret != KErrNone) || !iActiveSchedulerwait) {
CleanupStack::PopAndDestroy(trig);
return FALSE;
}
iTriggerCreation = FALSE;
//create a trigger asynchronously
iLbt.CreateTrigger(*trig, triggerID, ETrue, iStatus);
SetActive();
//wait till the iActiveSchedularwait->AsyncStop() is called in RunL
iActiveSchedulerwait->Start();
delete iActiveSchedulerwait;
CleanupStack::PopAndDestroy(trig);
//if the trigger creation is successful, add the triggerinfo to the linked list
if (iTriggerCreation == TRUE)
iTriggerMonitorInfo->addMonitorTriggerInfo(aParent, triggerID, aType);
delete req;
return iTriggerCreation;
} else { //triggerinfo available in the linked list
CLbtSessionTrigger* trig = NULL;
//Define the triggering area
CLbtGeoCircle* trigArea = NULL;
TRAP(ret, trigArea = CLbtGeoCircle::NewL(
aCoordinate , //center coordinate
aRadius //radius in meters. If
//NaN is used, Location
//Triggering Server will
//use minimal size of trigger
//area as the radius of the
//trigger
));
if ((ret != KErrNone) || (!trigArea)) {
return FALSE;
}
CleanupStack::PushL(trigArea);
//2: Construct a entry type of trigger condition
CLbtTriggerConditionArea* cond = NULL;
if (aType == EntryTrigger) {
//2: Construct a entry type of trigger condition
TRAP(ret, cond = CLbtTriggerConditionArea::NewL(
trigArea,
CLbtTriggerConditionArea::EFireOnEnter
));
} else if (aType == ExitTrigger) {
TRAP(ret, cond = CLbtTriggerConditionArea::NewL(
trigArea,
CLbtTriggerConditionArea::EFireOnExit
));
}
if ((ret != KErrNone) || !cond) {
CleanupStack::PopAndDestroy(trigArea);
return FALSE;
}
CleanupStack::Pop(trigArea); //ownership of trigArea is transferred.
CleanupStack::PushL(cond);
//create a session trigger
TRAP(ret, trig = CLbtSessionTrigger::NewL());
if ((ret != KErrNone) || (!trig)) {
CleanupStack::PopAndDestroy(cond);
return FALSE;
}
//set the condition for the trigger
trig->SetCondition(cond);
CleanupStack::Pop(cond);
CleanupStack::PushL(trig);
//set the trigger ID
trig->SetId(triggerInfo->iTriggerID);
iLbt.SetTriggerStateL(triggerInfo->iTriggerID, CLbtTriggerEntry::EStateDisabled, ELbtTrue);
//update the trigger with the new condition in LBT server
TRAP(ret, iLbt.UpdateTriggerL(*trig, CLbtTriggerEntry::EAttributeCondition, ELbtTrue));
CleanupStack::PopAndDestroy(trig);
if (ret != KErrNone) {
return FALSE;;
}
return TRUE;
}
}
QMLBackendMonitorCreateTriggerAO::~QMLBackendMonitorCreateTriggerAO()
{
Cancel();
iLbt.Close(); //closes the subsession
}
void QMLBackendMonitorCreateTriggerAO::DoCancel()
{
if (!IsActive()) {
iActiveSchedulerwait->AsyncStop();
}
}
void QMLBackendMonitorCreateTriggerAO::RunL()
{
switch (iStatus.Int()) {
case KErrNone :
iTriggerCreation = TRUE;
break;
default :
break;
}
//stops the AO, waiting in the iActiveSchedulerwait->Start()
iActiveSchedulerwait->AsyncStop();
}
QMLBackendMonitorCreateTriggerAO* QMLBackendMonitorCreateTriggerAO::NewL(QGeoAreaMonitorS60* aParent , RLbtServer &aLbt)
{
QMLBackendMonitorCreateTriggerAO* self = QMLBackendMonitorCreateTriggerAO::
NewLC(aParent, aLbt);
CleanupStack::Pop();
return self;
}
QMLBackendMonitorCreateTriggerAO* QMLBackendMonitorCreateTriggerAO::NewLC(QGeoAreaMonitorS60* aParent , RLbtServer &aLbtServer)
{
QMLBackendMonitorCreateTriggerAO *self = new(ELeave) QMLBackendMonitorCreateTriggerAO;
CleanupStack::PushL(self);
self->ConstructL(aLbtServer);
if (!self->isValid()) {
delete self;
self = NULL;
}
return self;
}
void QMLBackendMonitorCreateTriggerAO::ConstructL(RLbtServer &aLbtServ)
{
if (iLbt.Open(aLbtServ) == KErrNone) { //opens the subseesion
subsessionCreated = TRUE;
//get the singleton object of CBackendMonitorInfo class
iTriggerMonitorInfo = CBackendMonitorInfo::NewL();
}
}
QMLBackendMonitorCreateTriggerAO::QMLBackendMonitorCreateTriggerAO()
: CActive(EPriorityStandard), // Standard priority
subsessionCreated(FALSE), iTriggerCreation(FALSE)
{
CActiveScheduler::Add(this); //add AO to the Schedular
}
//Enables/Disables the trigger state depending on the aStatus
void QMLBackendMonitorCreateTriggerAO::SetTriggerState(QGeoAreaMonitorS60* aParent, enTriggerType aType, bool aStatus)
{
//retrieve the triggerinfo from the linked list from the supplied aPrent and aType
CMonitorTriggerInfo* triggerInfo = iTriggerMonitorInfo->getMonitorTriggerInfo(aParent, aType);
if (aStatus == true) {
TRAPD(err, iLbt.SetTriggerStateL(triggerInfo->iTriggerID, CLbtTriggerEntry::EStateEnabled, ELbtTrue));
} else {
TRAPD(err, iLbt.SetTriggerStateL(triggerInfo->iTriggerID, CLbtTriggerEntry::EStateDisabled, ELbtTrue));
}
}
//checks whether trigger is Initialized. The trigger entry corresponding to the aParent and aType is
//searched in the linked list
bool QMLBackendMonitorCreateTriggerAO::isTriggerInitialized(QGeoAreaMonitorS60* aParent, enTriggerType aType)
{
CMonitorTriggerInfo* triggerInfo = iTriggerMonitorInfo->getMonitorTriggerInfo(aParent, aType);
return (triggerInfo != NULL) ? TRUE : FALSE;
}
QTM_END_NAMESPACE