qtmobility/src/location/qmlbackendao_s60.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qtmobility/src/location/qmlbackendao_s60.cpp	Fri Apr 16 15:51:22 2010 +0300
@@ -0,0 +1,476 @@
+/****************************************************************************
+**
+** 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);
+
+    //setUpdateInterval(aTimeout);
+    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 :
+
+            //Posiiton Module is unable to return any position information
+        case KPositionQualityLoss :
+
+            //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
+                    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;
+
+            //request was successfully cancelled
+        case KErrCancel :
+            break;
+
+        default :
+            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) {
+        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
+    TInt 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
+            mPositioner.NotifyPositionUpdate(mPosSatInfo , iStatus);
+
+        SetActive();
+
+    }
+}
+
+QTM_END_NAMESPACE