summaryrefslogtreecommitdiff
path: root/src/location/qmlbackendao_s60.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/location/qmlbackendao_s60.cpp')
-rw-r--r--src/location/qmlbackendao_s60.cpp478
1 files changed, 478 insertions, 0 deletions
diff --git a/src/location/qmlbackendao_s60.cpp b/src/location/qmlbackendao_s60.cpp
new file mode 100644
index 00000000..8674f37e
--- /dev/null
+++ b/src/location/qmlbackendao_s60.cpp
@@ -0,0 +1,478 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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 "qgeopositioninfosource_s60_p.h"
+#include "qgeosatelliteinfosource_s60_p.h"
+#include "qmlbackendao_s60_p.h"
+
+QTM_BEGIN_NAMESPACE
+
+//The name of the requestor //Added by PM
+//_LIT(KRequestor,"QTMobility Location");
+
+// constructor
+CQMLBackendAO::CQMLBackendAO() :
+ CActive(EPriorityStandard), // Standard priority
+ mPosInfo(NULL),
+ mRequester(NULL),
+ mRequesterSatellite(NULL),
+ mRequestType(RequestType(0))
+{
+}
+
+//
+//
+//
+CQMLBackendAO* CQMLBackendAO::NewLC(QObject *aRequester,
+ RequestType aRequestType, TPositionModuleId aModId)
+{
+ CQMLBackendAO* self = new(ELeave) CQMLBackendAO();
+ CleanupStack::PushL(self);
+ self->ConstructL(aRequester, aRequestType, aModId);
+ return self;
+}
+
+//
+//
+//
+CQMLBackendAO* CQMLBackendAO::NewL(QObject *aRequester,
+ RequestType aRequestType, TPositionModuleId aModId)
+{
+ CQMLBackendAO* self = CQMLBackendAO::NewLC(aRequester, aRequestType, aModId);
+ CleanupStack::Pop(); // self;
+ return self;
+}
+
+//
+//
+//
+TInt CQMLBackendAO::ConstructL(QObject *aRequester, RequestType aRequestType,
+ TPositionModuleId aModId)
+{
+ TInt error = KErrNone;
+ RPositionServer PosServer;
+
+ if (aRequester->inherits("QGeoSatelliteInfoSource"))
+ mRequesterSatellite = static_cast<CQGeoSatelliteInfoSourceS60*>(aRequester);
+ else
+ mRequester = static_cast<CQGeoPositionInfoSourceS60*>(aRequester);
+
+ mRequestType = aRequestType;
+
+ if ((mRequestType == RegularUpdate) || (mRequestType == OnceUpdate)) {
+ if (aRequester->inherits("QGeoSatelliteInfoSource"))
+ PosServer = mRequesterSatellite->getPositionServer();
+ else
+ PosServer = mRequester->getPositionServer();
+
+ error = mPositioner.Open(PosServer, aModId);
+
+ if (error != KErrNone)
+ return error;
+
+ CleanupClosePushL(mPositioner);
+
+ error = mPositioner.SetRequestor(CRequestor::ERequestorService ,
+ CRequestor::EFormatApplication, _L("QTmobility_Location"));
+
+ CleanupStack::Pop(1);
+
+ if (error != KErrNone)
+ return error;
+
+ }
+
+ CActiveScheduler::Add(this); // Add to scheduler
+
+ return error;
+}
+
+//
+CQMLBackendAO::~CQMLBackendAO()
+{
+ Cancel();
+
+ if ((mRequestType == OnceUpdate) || (mRequestType == RegularUpdate)) {
+ //close the subsession
+ mPositioner.Close();
+
+ if (mPosInfo) {
+ mPosInfo->ClearRequestedFields();
+
+ mPosInfo->ClearPositionData();
+ //delete the HPositionGenericInfo
+ delete mPosInfo;
+ }
+ } else if (mRequestType == DeviceStatus) {
+ RPositionServer posServer;
+
+ //done only by the position server Active Object
+ if (mRequester)
+ posServer = mRequester->getPositionServer();
+ else
+ posServer = mRequesterSatellite->getPositionServer();
+
+ posServer.Close();
+ }
+}
+
+//
+void CQMLBackendAO::DoCancel()
+{
+ CancelAll();
+}
+
+
+//
+void CQMLBackendAO::RunL()
+{
+ switch (mRequestType) {
+ case DeviceStatus :
+ handleDeviceNotification(iStatus.Int());
+ break;
+ case RegularUpdate :
+ case OnceUpdate:
+ handlePosUpdateNotification(iStatus.Int());
+ break;
+ default :
+ break;
+ }
+}
+
+//
+TInt CQMLBackendAO::RunError(TInt aError)
+{
+ return aError;
+}
+
+
+// checks any pending request in activeobject
+bool CQMLBackendAO::isRequestPending()
+{
+ if (IsActive())
+ return true;
+ else
+ return false;
+}
+
+
+
+// Async call to get notifications about device status.
+void CQMLBackendAO::notifyDeviceStatus(TPositionModuleStatusEventBase &aStatusEvent)
+{
+ RPositionServer PosServ;
+
+ if (mRequester)
+ PosServ = mRequester->getPositionServer();
+ else
+ PosServ = mRequesterSatellite->getPositionServer();
+
+ //register for device status events
+ TPositionModuleStatusEventBase::TModuleEvent RequestedEvents(
+ TPositionModuleStatusEventBase::EEventDeviceStatus);
+
+ aStatusEvent.SetRequestedEvents(RequestedEvents);
+
+ PosServ.NotifyModuleStatusEvent(aStatusEvent, iStatus);
+
+ SetActive();
+
+}
+
+void CQMLBackendAO::CancelAll()
+{
+
+ RPositionServer PosServer;
+ if (mRequestType == DeviceStatus) {
+ if (mRequester)
+ PosServer = mRequester->getPositionServer();
+ else
+ PosServer = mRequesterSatellite->getPositionServer();
+
+ PosServer.CancelRequest(EPositionServerNotifyModuleStatusEvent);
+ } else if ((mRequestType == OnceUpdate) || (mRequestType == RegularUpdate)) {
+ mPositioner.CancelRequest(EPositionerNotifyPositionUpdate);
+ }
+
+}
+
+//Initialize the posInfo with appropriate fields
+bool CQMLBackendAO::initializePosInfo()
+{
+ if (!mPosInfo) {
+ mPosInfo = HPositionGenericInfo::New();
+
+ if (mPosInfo == NULL)
+ return FALSE;
+ } else {
+ mPosInfo->ClearRequestedFields();
+
+ mPosInfo->ClearPositionData();
+ }
+ RPositionServer posServer;
+ TPositionModuleInfo moduleInfo;
+ TInt error = KErrNone;
+
+ //get the posiiton server
+ posServer = mRequester->getPositionServer();
+
+ //retrieve the module id used by the posiitoner
+ if (mRequestType == RegularUpdate)
+ error = posServer.GetModuleInfoById(mRequester->getCurrentPositonModuleID(), moduleInfo);
+ else
+ error = posServer.GetModuleInfoById(mRequester->getRequestUpdateModuleID(), moduleInfo);
+
+ if (error == KErrNone) {
+
+ //get capabilities of the module
+ TPositionModuleInfo::TCapabilities caps = moduleInfo.Capabilities();
+
+ if (caps & TPositionModuleInfo::ECapabilitySatellite) {
+ mPosInfo->SetRequestedField(EPositionFieldSatelliteNumInView);
+ mPosInfo->SetRequestedField(EPositionFieldSatelliteNumUsed);
+ }
+
+ if (caps & TPositionModuleInfo::ECapabilitySpeed) {
+ mPosInfo->SetRequestedField(EPositionFieldHorizontalSpeed);
+ mPosInfo->SetRequestedField(EPositionFieldVerticalSpeed);
+ }
+ if (caps & TPositionModuleInfo::ECapabilityCompass) {
+ mPosInfo->SetRequestedField(EPositionFieldMagneticCourseError);
+ mPosInfo->SetRequestedField(EPositionFieldHeading);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//requestUpdate : request for position update once
+void CQMLBackendAO::requestUpdate(int aTimeout)
+{
+ TPositionUpdateOptions aPosOption;
+
+ mPositioner.GetUpdateOptions(aPosOption);
+
+ aPosOption.SetUpdateInterval(TTimeIntervalMicroSeconds(0));
+
+ aPosOption.SetUpdateTimeOut(TTimeIntervalMicroSeconds(aTimeout * 1000));
+
+ mPositioner.SetUpdateOptions(aPosOption);
+
+ startUpdates();
+}
+
+
+//
+void CQMLBackendAO::cancelUpdate()
+{
+ Cancel();
+
+}
+
+
+//
+void CQMLBackendAO::handleDeviceNotification(int aError)
+{
+ switch (aError) {
+ //NotifyPositionModulestatusEvent successfully completed
+ case KErrNone :
+
+ //module not found
+ case KErrNotFound :
+ if (mRequester)
+ mRequester->updateDeviceStatus();
+ else
+ mRequesterSatellite->updateDeviceStatus();
+ break;
+
+ //request has been successfully cancelled
+ case KErrCancel :
+ break;
+
+ //unrecoverabe errors
+ default :
+ break;
+ }
+}
+
+
+//
+void CQMLBackendAO::handlePosUpdateNotification(int aError)
+{
+
+ HPositionGenericInfo *positionInfo = NULL;
+
+ TPositionSatelliteInfo satInfo;
+ switch (aError) {
+ //NotifyPositionUpdate successfully completed
+ case KErrNone :
+
+
+ //requested information could not be retrieved within the maximum peroid
+ case KErrTimedOut:
+
+
+
+ if (mRequester) {
+ positionInfo = HPositionGenericInfo::New();
+
+ if (positionInfo == NULL)
+ return;
+
+ //copy the buffer contents into a new HPositionGenericInfo buffer,to be used
+ //for creating QGeoPositionInfo object later
+ memcpy(positionInfo , mPosInfo , mPosInfo->BufferSize());
+ } else {
+ satInfo = mPosSatInfo;
+ }
+
+ //if regUpdateAO, request for the next update
+ if (mRequestType == RegularUpdate) {
+ if (mRequester) {
+ initializePosInfo();
+ mPositioner.NotifyPositionUpdate(*mPosInfo, iStatus);
+ } else {
+ mPosSatInfo.ClearSatellitesInView();
+ mPositioner.NotifyPositionUpdate(mPosSatInfo, iStatus);
+ }
+
+ SetActive();
+ }
+
+ if (mRequester) {
+ mRequester->updatePosition(positionInfo, aError);
+ delete positionInfo;
+ } else {
+ if ((aError != KErrTimedOut) || (mRequestType != RegularUpdate)) {
+ mRequesterSatellite->updatePosition(satInfo, aError, (mRequestType == RegularUpdate));
+ }
+ }
+
+ break;
+
+ default :
+ if (mRequester) {
+ mRequester->updatePosition(positionInfo, aError); // positionInfo will be NULL
+ } else {
+ mRequesterSatellite->updatePosition(satInfo, aError, (mRequestType == RegularUpdate));
+ }
+ break;
+
+ }
+}
+
+//////////////////////////////////////////////////////////////
+// Sets the interval for getting the regular notification //
+// the time interval set is in milli seconds //
+//////////////////////////////////////////////////////////////
+int CQMLBackendAO::setUpdateInterval(int aMilliSec)
+{
+ int minimumUpdateInterval = 0;
+ TInt64 mUpdateInterval = 0 ;
+
+
+ if (mRequester)
+ minimumUpdateInterval = mRequester->minimumUpdateInterval();
+ else
+ minimumUpdateInterval = mRequesterSatellite->minimumUpdateInterval();
+
+ if (minimumUpdateInterval < 0)
+ minimumUpdateInterval = 100;
+ // if the current requesttype is regular updates
+ // then set the updateinterval otherwise ignore
+ //if(mRequestType != REQ_REG_UPDATE)
+ // return;
+
+ TPositionUpdateOptions aPosOption;
+
+ TInt error = mPositioner.GetUpdateOptions(aPosOption);
+
+ // TTimeIntervalMicroSeconds is converted seconds
+ TInt currentUpdateInterval = aPosOption.UpdateInterval().Int64() / 1000;
+
+ // If msec is not 0 and is less than the value returned by minimumUpdateInterval(),
+ // the interval will be set to the minimum interval.
+ // if (aMilliSec != 0 && aMilliSec <= minimumUpdateInterval) {
+ // workaround, not accepting zero as value, see QTMOBILITY-995
+ if (aMilliSec <= minimumUpdateInterval) {
+ mUpdateInterval = minimumUpdateInterval;
+ } else {
+ mUpdateInterval = aMilliSec;
+ }
+
+ // if the same value is being set then just ignore it.
+ if (currentUpdateInterval == mUpdateInterval) {
+ return mUpdateInterval;
+ }
+
+ // will set Either zero, minimum or +ve value
+ // seconds converted to TTimeIntervalMicroSeconds
+ aPosOption.SetUpdateInterval(TTimeIntervalMicroSeconds(mUpdateInterval * 1000));
+ // set the timeout to the smaller of 150% of interval or update interval + 10 seconds
+ TInt64 mUpdateTimeout = (mUpdateInterval * 3) / 2;
+ if (mUpdateTimeout > mUpdateInterval + 10000)
+ mUpdateTimeout = mUpdateInterval + 10000;
+
+ if (aMilliSec > 0)
+ aPosOption.SetUpdateTimeOut(TTimeIntervalMicroSeconds(mUpdateTimeout * 1000));
+
+ error = mPositioner.SetUpdateOptions(aPosOption);
+
+ return mUpdateInterval;
+}
+
+void CQMLBackendAO::startUpdates()
+{
+ if (!IsActive()) {
+ if (mRequester) {
+ initializePosInfo();
+ mPositioner.NotifyPositionUpdate(*mPosInfo , iStatus);
+ } else {
+ mPosSatInfo.ClearSatellitesInView();
+ mPositioner.NotifyPositionUpdate(mPosSatInfo , iStatus);
+ }
+
+ SetActive();
+
+ }
+}
+
+QTM_END_NAMESPACE