src/location/qmlbackendao_s60.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qgeopositioninfosource_s60_p.h"
       
    43 #include "qgeosatelliteinfosource_s60_p.h"
       
    44 #include "qmlbackendao_s60_p.h"
       
    45 
       
    46 QTM_BEGIN_NAMESPACE
       
    47 
       
    48 //The name of the requestor //Added by PM
       
    49 //_LIT(KRequestor,"QTMobility Location");
       
    50 
       
    51 // constructor
       
    52 CQMLBackendAO::CQMLBackendAO() :
       
    53         CActive(EPriorityStandard), // Standard priority
       
    54         mPosInfo(NULL),
       
    55         mRequester(NULL),
       
    56         mRequesterSatellite(NULL),
       
    57         mRequestType(RequestType(0))
       
    58 {
       
    59 }
       
    60 
       
    61 //
       
    62 //
       
    63 //
       
    64 CQMLBackendAO* CQMLBackendAO::NewLC(QObject *aRequester,
       
    65                                     RequestType  aRequestType, TPositionModuleId  aModId)
       
    66 {
       
    67     CQMLBackendAO* self = new(ELeave) CQMLBackendAO();
       
    68     CleanupStack::PushL(self);
       
    69     self->ConstructL(aRequester, aRequestType, aModId);
       
    70     return self;
       
    71 }
       
    72 
       
    73 //
       
    74 //
       
    75 //
       
    76 CQMLBackendAO* CQMLBackendAO::NewL(QObject *aRequester,
       
    77                                    RequestType  aRequestType, TPositionModuleId  aModId)
       
    78 {
       
    79     CQMLBackendAO* self = CQMLBackendAO::NewLC(aRequester, aRequestType, aModId);
       
    80     CleanupStack::Pop(); // self;
       
    81     return self;
       
    82 }
       
    83 
       
    84 //
       
    85 //
       
    86 //
       
    87 TInt CQMLBackendAO::ConstructL(QObject *aRequester, RequestType  aRequestType,
       
    88                                TPositionModuleId  aModId)
       
    89 {
       
    90     TInt error = KErrNone;
       
    91     RPositionServer PosServer;
       
    92 
       
    93     if (aRequester->inherits("QGeoSatelliteInfoSource"))
       
    94         mRequesterSatellite = static_cast<CQGeoSatelliteInfoSourceS60*>(aRequester);
       
    95     else
       
    96         mRequester = static_cast<CQGeoPositionInfoSourceS60*>(aRequester);
       
    97 
       
    98     mRequestType = aRequestType;
       
    99 
       
   100     if ((mRequestType == RegularUpdate) || (mRequestType == OnceUpdate)) {
       
   101         if (aRequester->inherits("QGeoSatelliteInfoSource"))
       
   102             PosServer = mRequesterSatellite->getPositionServer();
       
   103         else
       
   104             PosServer = mRequester->getPositionServer();
       
   105 
       
   106         error  =  mPositioner.Open(PosServer, aModId);
       
   107 
       
   108         if (error != KErrNone)
       
   109             return error;
       
   110 
       
   111         CleanupClosePushL(mPositioner);
       
   112 
       
   113         error = mPositioner.SetRequestor(CRequestor::ERequestorService ,
       
   114                                          CRequestor::EFormatApplication, _L("QTmobility_Location"));
       
   115 
       
   116         CleanupStack::Pop(1);
       
   117 
       
   118         if (error != KErrNone)
       
   119             return error;
       
   120 
       
   121     }
       
   122 
       
   123     CActiveScheduler::Add(this); // Add to scheduler
       
   124 
       
   125     return error;
       
   126 }
       
   127 
       
   128 //
       
   129 CQMLBackendAO::~CQMLBackendAO()
       
   130 {
       
   131     Cancel();
       
   132 
       
   133     if ((mRequestType == OnceUpdate) || (mRequestType == RegularUpdate)) {
       
   134         //close the subsession
       
   135         mPositioner.Close();
       
   136 
       
   137         if (mPosInfo) {
       
   138             mPosInfo->ClearRequestedFields();
       
   139 
       
   140             mPosInfo->ClearPositionData();
       
   141             //delete the HPositionGenericInfo
       
   142             delete mPosInfo;
       
   143         }
       
   144     } else if (mRequestType == DeviceStatus) {
       
   145         RPositionServer posServer;
       
   146 
       
   147         //done only by the position server Active Object
       
   148         if (mRequester)
       
   149             posServer = mRequester->getPositionServer();
       
   150         else
       
   151             posServer = mRequesterSatellite->getPositionServer();
       
   152 
       
   153         posServer.Close();
       
   154     }
       
   155 }
       
   156 
       
   157 //
       
   158 void CQMLBackendAO::DoCancel()
       
   159 {
       
   160     CancelAll();
       
   161 }
       
   162 
       
   163 
       
   164 //
       
   165 void CQMLBackendAO::RunL()
       
   166 {
       
   167     switch (mRequestType) {
       
   168         case DeviceStatus :
       
   169             handleDeviceNotification(iStatus.Int());
       
   170             break;
       
   171         case RegularUpdate :
       
   172         case OnceUpdate:
       
   173             handlePosUpdateNotification(iStatus.Int());
       
   174             break;
       
   175         default         :
       
   176             break;
       
   177     }
       
   178 }
       
   179 
       
   180 //
       
   181 TInt CQMLBackendAO::RunError(TInt aError)
       
   182 {
       
   183     return aError;
       
   184 }
       
   185 
       
   186 
       
   187 // checks any pending request in activeobject
       
   188 bool CQMLBackendAO::isRequestPending()
       
   189 {
       
   190     if (IsActive())
       
   191         return true;
       
   192     else
       
   193         return false;
       
   194 }
       
   195 
       
   196 
       
   197 
       
   198 // Async call to get notifications about device status.
       
   199 void CQMLBackendAO::notifyDeviceStatus(TPositionModuleStatusEventBase &aStatusEvent)
       
   200 {
       
   201     RPositionServer PosServ;
       
   202 
       
   203     if (mRequester)
       
   204         PosServ = mRequester->getPositionServer();
       
   205     else
       
   206         PosServ = mRequesterSatellite->getPositionServer();
       
   207 
       
   208     //register for device status events
       
   209     TPositionModuleStatusEventBase::TModuleEvent RequestedEvents(
       
   210         TPositionModuleStatusEventBase::EEventDeviceStatus);
       
   211 
       
   212     aStatusEvent.SetRequestedEvents(RequestedEvents);
       
   213 
       
   214     PosServ.NotifyModuleStatusEvent(aStatusEvent, iStatus);
       
   215 
       
   216     SetActive();
       
   217 
       
   218 }
       
   219 
       
   220 void CQMLBackendAO::CancelAll()
       
   221 {
       
   222 
       
   223     RPositionServer PosServer;
       
   224     if (mRequestType == DeviceStatus) {
       
   225         if (mRequester)
       
   226             PosServer = mRequester->getPositionServer();
       
   227         else
       
   228             PosServer = mRequesterSatellite->getPositionServer();
       
   229 
       
   230         PosServer.CancelRequest(EPositionServerNotifyModuleStatusEvent);
       
   231     } else if ((mRequestType == OnceUpdate) || (mRequestType == RegularUpdate)) {
       
   232         mPositioner.CancelRequest(EPositionerNotifyPositionUpdate);
       
   233     }
       
   234 
       
   235 }
       
   236 
       
   237 //Initialize the posInfo with appropriate fields
       
   238 bool CQMLBackendAO::initializePosInfo()
       
   239 {
       
   240     if (!mPosInfo) {
       
   241         mPosInfo = HPositionGenericInfo::New();
       
   242 
       
   243         if (mPosInfo == NULL)
       
   244             return FALSE;
       
   245     } else {
       
   246         mPosInfo->ClearRequestedFields();
       
   247 
       
   248         mPosInfo->ClearPositionData();
       
   249     }
       
   250     RPositionServer posServer;
       
   251     TPositionModuleInfo moduleInfo;
       
   252     TInt error = KErrNone;
       
   253 
       
   254     //get the posiiton server
       
   255     posServer = mRequester->getPositionServer();
       
   256 
       
   257     //retrieve the module id used by the posiitoner
       
   258     if (mRequestType == RegularUpdate)
       
   259         error = posServer.GetModuleInfoById(mRequester->getCurrentPositonModuleID(), moduleInfo);
       
   260     else
       
   261         error = posServer.GetModuleInfoById(mRequester->getRequestUpdateModuleID(), moduleInfo);
       
   262 
       
   263     if (error == KErrNone) {
       
   264 
       
   265         //get capabilities of the module
       
   266         TPositionModuleInfo::TCapabilities caps = moduleInfo.Capabilities();
       
   267 
       
   268         if (caps & TPositionModuleInfo::ECapabilitySatellite) {
       
   269             mPosInfo->SetRequestedField(EPositionFieldSatelliteNumInView);
       
   270             mPosInfo->SetRequestedField(EPositionFieldSatelliteNumUsed);
       
   271         }
       
   272 
       
   273         if (caps & TPositionModuleInfo::ECapabilitySpeed) {
       
   274             mPosInfo->SetRequestedField(EPositionFieldHorizontalSpeed);
       
   275             mPosInfo->SetRequestedField(EPositionFieldVerticalSpeed);
       
   276         }
       
   277         if (caps & TPositionModuleInfo::ECapabilityCompass) {
       
   278             mPosInfo->SetRequestedField(EPositionFieldMagneticCourseError);
       
   279             mPosInfo->SetRequestedField(EPositionFieldHeading);
       
   280         }
       
   281         return TRUE;
       
   282     }
       
   283     return FALSE;
       
   284 }
       
   285 
       
   286 //requestUpdate : request for position update once
       
   287 void CQMLBackendAO::requestUpdate(int aTimeout)
       
   288 {
       
   289     TPositionUpdateOptions  aPosOption;
       
   290 
       
   291     mPositioner.GetUpdateOptions(aPosOption);
       
   292 
       
   293     aPosOption.SetUpdateInterval(TTimeIntervalMicroSeconds(0));
       
   294 
       
   295     aPosOption.SetUpdateTimeOut(TTimeIntervalMicroSeconds(aTimeout * 1000));
       
   296 
       
   297     mPositioner.SetUpdateOptions(aPosOption);
       
   298 
       
   299     startUpdates();
       
   300 }
       
   301 
       
   302 
       
   303 //
       
   304 void CQMLBackendAO::cancelUpdate()
       
   305 {
       
   306     Cancel();
       
   307 
       
   308 }
       
   309 
       
   310 
       
   311 //
       
   312 void CQMLBackendAO::handleDeviceNotification(int aError)
       
   313 {
       
   314     switch (aError) {
       
   315             //NotifyPositionModulestatusEvent successfully completed
       
   316         case KErrNone :
       
   317 
       
   318             //module not found
       
   319         case KErrNotFound :
       
   320             if (mRequester)
       
   321                 mRequester->updateDeviceStatus();
       
   322             else
       
   323                 mRequesterSatellite->updateDeviceStatus();
       
   324             break;
       
   325 
       
   326             //request has been successfully cancelled
       
   327         case KErrCancel :
       
   328             break;
       
   329 
       
   330             //unrecoverabe errors
       
   331         default :
       
   332             break;
       
   333     }
       
   334 }
       
   335 
       
   336 
       
   337 //
       
   338 void CQMLBackendAO::handlePosUpdateNotification(int aError)
       
   339 {
       
   340 
       
   341     HPositionGenericInfo *positionInfo = NULL;
       
   342 
       
   343     TPositionSatelliteInfo satInfo;
       
   344     switch (aError) {
       
   345             //NotifyPositionUpdate successfully completed
       
   346         case KErrNone :
       
   347 
       
   348             //Posiiton Module is unable to return any position information
       
   349         case KPositionQualityLoss :
       
   350 
       
   351             //requested information could not be retrieved within the maximum peroid
       
   352         case KErrTimedOut:
       
   353 
       
   354 
       
   355 
       
   356             if (mRequester) {
       
   357                 positionInfo = HPositionGenericInfo::New();
       
   358 
       
   359                 if (positionInfo == NULL)
       
   360                     return;
       
   361 
       
   362                 //copy the buffer contents into a new HPositionGenericInfo buffer,to be used
       
   363                 //for creating QGeoPositionInfo object later
       
   364                 memcpy(positionInfo , mPosInfo , mPosInfo->BufferSize());
       
   365             } else {
       
   366                 satInfo  = mPosSatInfo;
       
   367             }
       
   368 
       
   369             //if regUpdateAO, request for the next update
       
   370             if (mRequestType == RegularUpdate) {
       
   371                 if (mRequester) {
       
   372                     initializePosInfo();
       
   373                     mPositioner.NotifyPositionUpdate(*mPosInfo, iStatus);
       
   374                 } else
       
   375                     mPositioner.NotifyPositionUpdate(mPosSatInfo, iStatus);
       
   376 
       
   377                 SetActive();
       
   378             }
       
   379 
       
   380             if (mRequester) {
       
   381                 mRequester->updatePosition(positionInfo, aError);
       
   382                 delete positionInfo;
       
   383             } else {
       
   384                 if ((aError != KErrTimedOut) || (mRequestType != RegularUpdate)) {
       
   385                     mRequesterSatellite->updatePosition(satInfo, aError, (mRequestType == RegularUpdate));
       
   386                 }
       
   387             }
       
   388 
       
   389             break;
       
   390 
       
   391             //request was successfully cancelled
       
   392         case KErrCancel :
       
   393             break;
       
   394 
       
   395         default :
       
   396             break;
       
   397 
       
   398     }
       
   399 }
       
   400 
       
   401 //////////////////////////////////////////////////////////////
       
   402 // Sets the interval for getting the regular notification   //
       
   403 // the time interval set is in milli seconds                      //
       
   404 //////////////////////////////////////////////////////////////
       
   405 int CQMLBackendAO::setUpdateInterval(int aMilliSec)
       
   406 {
       
   407     int minimumUpdateInterval = 0;
       
   408     TInt64 mUpdateInterval = 0 ;
       
   409 
       
   410     if (mRequester)
       
   411         minimumUpdateInterval = mRequester->minimumUpdateInterval();
       
   412     else
       
   413         minimumUpdateInterval = mRequesterSatellite->minimumUpdateInterval();
       
   414 
       
   415     if (minimumUpdateInterval < 0)
       
   416         minimumUpdateInterval = 100;
       
   417     // if the current requesttype is  regular updates
       
   418     // then set the updateinterval otherwise ignore
       
   419     //if(mRequestType != REQ_REG_UPDATE)
       
   420     //    return;
       
   421 
       
   422     TPositionUpdateOptions  aPosOption;
       
   423 
       
   424     TInt error = mPositioner.GetUpdateOptions(aPosOption);
       
   425 
       
   426     // TTimeIntervalMicroSeconds is converted seconds
       
   427     TInt currentUpdateInterval  = aPosOption.UpdateInterval().Int64() / 1000;
       
   428 
       
   429     // If msec is not 0 and is less than the value returned by minimumUpdateInterval(),
       
   430     // the interval will be set to the minimum interval.
       
   431     if (aMilliSec != 0 && aMilliSec <= minimumUpdateInterval) {
       
   432         mUpdateInterval = minimumUpdateInterval;
       
   433     } else {
       
   434         mUpdateInterval = aMilliSec;
       
   435     }
       
   436 
       
   437     // if the same value is being set then just ignore it.
       
   438     if (currentUpdateInterval == mUpdateInterval) {
       
   439         return mUpdateInterval;
       
   440     }
       
   441 
       
   442     // will set Either zero, minimum or +ve value
       
   443     // seconds converted to TTimeIntervalMicroSeconds
       
   444     aPosOption.SetUpdateInterval(TTimeIntervalMicroSeconds(mUpdateInterval * 1000));
       
   445 
       
   446     // set the timeout to the smaller of 150% of interval or update interval + 10 seconds
       
   447     TInt64 mUpdateTimeout = (mUpdateInterval * 3) / 2;
       
   448     if (mUpdateTimeout > mUpdateInterval + 10000)
       
   449         mUpdateTimeout = mUpdateInterval + 10000;
       
   450 
       
   451     if (aMilliSec > 0)
       
   452         aPosOption.SetUpdateTimeOut(TTimeIntervalMicroSeconds(mUpdateTimeout * 1000));
       
   453 
       
   454     error = mPositioner.SetUpdateOptions(aPosOption);
       
   455 
       
   456     return mUpdateInterval;
       
   457 }
       
   458 
       
   459 void CQMLBackendAO::startUpdates()
       
   460 {
       
   461     if (!IsActive()) {
       
   462         if (mRequester) {
       
   463             initializePosInfo();
       
   464             mPositioner.NotifyPositionUpdate(*mPosInfo , iStatus);
       
   465         } else
       
   466             mPositioner.NotifyPositionUpdate(mPosSatInfo , iStatus);
       
   467 
       
   468         SetActive();
       
   469 
       
   470     }
       
   471 }
       
   472 
       
   473 QTM_END_NAMESPACE