qtmobility/src/location/liblocationwrapper.cpp
changeset 4 90517678cc4f
child 11 06b8e2af4411
equal deleted inserted replaced
1:2b40d63a9c3d 4:90517678cc4f
       
     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 "liblocationwrapper_p.h"
       
    43 
       
    44 using namespace std;
       
    45 
       
    46 QTM_BEGIN_NAMESPACE
       
    47 
       
    48 Q_GLOBAL_STATIC(LiblocationWrapper, LocationEngine)
       
    49         
       
    50 LiblocationWrapper *LiblocationWrapper::instance()
       
    51 {
       
    52     return LocationEngine();
       
    53 }
       
    54 
       
    55 LiblocationWrapper::~LiblocationWrapper() 
       
    56 {
       
    57     if (locationDevice)
       
    58         g_object_unref(locationDevice);
       
    59     if (locationControl)
       
    60         g_object_unref(locationControl);
       
    61 }
       
    62 
       
    63 bool LiblocationWrapper::inited()
       
    64 {
       
    65     int retval = false;
       
    66     if (!(locationState & LiblocationWrapper::Inited)) {
       
    67         g_type_init();
       
    68 
       
    69         locationControl = location_gpsd_control_get_default();
       
    70 
       
    71         if (locationControl) {
       
    72             g_object_set(G_OBJECT(locationControl),
       
    73                          "preferred-method", LOCATION_METHOD_USER_SELECTED,
       
    74                          "preferred-interval", LOCATION_INTERVAL_1S,
       
    75                          NULL);
       
    76             locationDevice = 
       
    77                     (LocationGPSDevice*)g_object_new(LOCATION_TYPE_GPS_DEVICE, 
       
    78                                                      NULL);
       
    79         
       
    80             if (locationDevice) {
       
    81                 errorHandlerId =
       
    82                     g_signal_connect(G_OBJECT(locationControl), "error-verbose",
       
    83                                      G_CALLBACK(&locationError), 
       
    84                                      static_cast<void*>(this));
       
    85                 posChangedId =
       
    86                     g_signal_connect(G_OBJECT(locationDevice), "changed",
       
    87                                      G_CALLBACK(&locationChanged), 
       
    88                                      static_cast<void*>(this));
       
    89                 locationState = LiblocationWrapper::Inited;
       
    90                 retval = true;
       
    91                 startcounter = 0;
       
    92             }
       
    93         }
       
    94     } else {
       
    95         retval = true;
       
    96     }
       
    97     return retval;
       
    98 }
       
    99 
       
   100 void LiblocationWrapper::locationError(LocationGPSDevice *device,
       
   101                                        gint errorCode, gpointer data)
       
   102 {
       
   103     Q_UNUSED(device);
       
   104     QString locationError;
       
   105 
       
   106     switch (errorCode) {
       
   107     case LOCATION_ERROR_USER_REJECTED_DIALOG:
       
   108         locationError = "User didn't enable requested methods";
       
   109         break;
       
   110     case LOCATION_ERROR_USER_REJECTED_SETTINGS:
       
   111         locationError = "User changed settings, which disabled location.";
       
   112         break;
       
   113     case LOCATION_ERROR_BT_GPS_NOT_AVAILABLE:
       
   114         locationError = "Problems with BT GPS";
       
   115         break;
       
   116     case LOCATION_ERROR_METHOD_NOT_ALLOWED_IN_OFFLINE_MODE:
       
   117         locationError = "Requested method is not allowed in offline mode";
       
   118         break;
       
   119     case LOCATION_ERROR_SYSTEM:
       
   120         locationError = "System error.";
       
   121         break;
       
   122     default:
       
   123         locationError = "Unknown error.";
       
   124     }
       
   125 
       
   126     qDebug() << "Location error:" << locationError;
       
   127 
       
   128     LiblocationWrapper *object;
       
   129     object = (LiblocationWrapper *)data;
       
   130     emit object->error();
       
   131 }
       
   132 
       
   133 void LiblocationWrapper::locationChanged(LocationGPSDevice *device,
       
   134                                                  gpointer data)
       
   135 {
       
   136     QGeoPositionInfo posInfo;
       
   137     QGeoCoordinate coordinate;
       
   138     QGeoSatelliteInfo satInfo;
       
   139     int satellitesInUseCount = 0;
       
   140     LiblocationWrapper *object;
       
   141     
       
   142     if (!data || !device) {
       
   143         return;
       
   144     }
       
   145     
       
   146     object = (LiblocationWrapper *)data;
       
   147 
       
   148     if (device) {
       
   149         if (device->fix) {
       
   150             if (device->fix->fields & LOCATION_GPS_DEVICE_TIME_SET) {
       
   151                 posInfo.setTimestamp(QDateTime::fromTime_t(device->fix->time));
       
   152             }
       
   153 
       
   154             if (device->fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET) {
       
   155                 coordinate.setLatitude(device->fix->latitude);
       
   156                 coordinate.setLongitude(device->fix->longitude);
       
   157                 posInfo.setAttribute(QGeoPositionInfo::HorizontalAccuracy,
       
   158                                      device->fix->eph);
       
   159                 posInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy,
       
   160                                      device->fix->epv);
       
   161             }
       
   162 
       
   163             if (device->fix->fields & LOCATION_GPS_DEVICE_ALTITUDE_SET) {
       
   164                 coordinate.setAltitude(device->fix->altitude);
       
   165             }
       
   166 
       
   167             if (device->fix->fields & LOCATION_GPS_DEVICE_SPEED_SET) {
       
   168                 posInfo.setAttribute(QGeoPositionInfo::GroundSpeed,
       
   169                                      device->fix->speed);
       
   170             }
       
   171 
       
   172             if (device->fix->fields & LOCATION_GPS_DEVICE_CLIMB_SET) {
       
   173                 posInfo.setAttribute(QGeoPositionInfo::VerticalSpeed,
       
   174                                      device->fix->climb);
       
   175             }
       
   176   
       
   177             if (device->fix->fields & LOCATION_GPS_DEVICE_TRACK_SET) {
       
   178                 posInfo.setAttribute(QGeoPositionInfo::Direction,
       
   179                                      device->fix->track);
       
   180             }
       
   181         }
       
   182         
       
   183         if (device->satellites_in_view) {
       
   184             QList<QGeoSatelliteInfo> satsInView;
       
   185             QList<QGeoSatelliteInfo> satsInUse;
       
   186             unsigned int i;
       
   187             for (i=0;i<device->satellites->len;i++) {
       
   188                 LocationGPSDeviceSatellite *satData =
       
   189                     (LocationGPSDeviceSatellite *)g_ptr_array_index(device->satellites,
       
   190                                                                     i);
       
   191                 satInfo.setSignalStrength(satData->signal_strength);
       
   192                 satInfo.setPrnNumber(satData->prn);
       
   193                 satInfo.setAttribute(QGeoSatelliteInfo::Elevation, 
       
   194                                      satData->elevation);
       
   195                 satInfo.setAttribute(QGeoSatelliteInfo::Azimuth, 
       
   196                                      satData->azimuth);
       
   197     
       
   198                 satsInView.append(satInfo);
       
   199                 if (satData->in_use) {
       
   200                     satellitesInUseCount++;
       
   201                     satsInUse.append(satInfo);
       
   202                 }
       
   203             }
       
   204             
       
   205             if (!satsInView.isEmpty())
       
   206                 object->satellitesInViewUpdated(satsInView);
       
   207             
       
   208             if (!satsInUse.isEmpty())
       
   209                 object->satellitesInUseUpdated(satsInUse);
       
   210         }        
       
   211     }
       
   212        
       
   213     posInfo.setCoordinate(coordinate);
       
   214 
       
   215     if ((device->fix->fields & LOCATION_GPS_DEVICE_TIME_SET) && 
       
   216         ((device->fix->mode == LOCATION_GPS_DEVICE_MODE_3D) || 
       
   217          (device->fix->mode == LOCATION_GPS_DEVICE_MODE_2D))) {
       
   218         object->setLocation(posInfo, true);
       
   219     } else {
       
   220         object->setLocation(posInfo, false);
       
   221     }
       
   222 }
       
   223 
       
   224 void LiblocationWrapper::setLocation(const QGeoPositionInfo &update, 
       
   225                                      bool locationValid)
       
   226 {
       
   227     validLastSatUpdate = locationValid;
       
   228     lastSatUpdate = update;
       
   229 }
       
   230 
       
   231 QGeoPositionInfo LiblocationWrapper::position() {
       
   232     return lastSatUpdate;
       
   233 }
       
   234 
       
   235 bool LiblocationWrapper::fixIsValid()
       
   236 {
       
   237     return validLastSatUpdate;
       
   238 }
       
   239 
       
   240 QGeoPositionInfo LiblocationWrapper::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
       
   241 {
       
   242     QGeoPositionInfo posInfo;
       
   243     QGeoCoordinate coordinate;
       
   244     double time;
       
   245     double latitude;
       
   246     double longitude;
       
   247     double altitude;
       
   248     double speed;
       
   249     double track;
       
   250     double climb;
       
   251     
       
   252     GConfItem lastKnownPositionTime("/system/nokia/location/lastknown/time");
       
   253     GConfItem lastKnownPositionLatitude("/system/nokia/location/lastknown/latitude");
       
   254     GConfItem lastKnownPositionLongitude("/system/nokia/location/lastknown/longitude");
       
   255     GConfItem lastKnownPositionAltitude("/system/nokia/location/lastknown/altitude");
       
   256     GConfItem lastKnownPositionSpeed("/system/nokia/location/lastknown/speed");
       
   257     GConfItem lastKnownPositionTrack("/system/nokia/location/lastknown/track");
       
   258     GConfItem lastKnownPositionClimb("/system/nokia/location/lastknown/climb");
       
   259     
       
   260     if (validLastSatUpdate)
       
   261         return lastSatUpdate;
       
   262 
       
   263     if (!fromSatellitePositioningMethodsOnly)
       
   264         if (validLastUpdate)
       
   265             return lastUpdate;
       
   266     
       
   267     time = lastKnownPositionTime.value().toDouble();
       
   268     latitude = lastKnownPositionLatitude.value().toDouble();
       
   269     longitude = lastKnownPositionLongitude.value().toDouble();
       
   270     altitude = lastKnownPositionAltitude.value().toDouble();
       
   271     speed = lastKnownPositionSpeed.value().toDouble();
       
   272     track = lastKnownPositionTrack.value().toDouble();
       
   273     climb = lastKnownPositionClimb.value().toDouble();
       
   274         
       
   275     if (longitude && latitude) {
       
   276         coordinate.setLongitude(longitude);
       
   277         coordinate.setLatitude(latitude);
       
   278         if (altitude) {
       
   279             coordinate.setAltitude(altitude);
       
   280         }
       
   281         posInfo.setCoordinate(coordinate);
       
   282     }
       
   283         
       
   284     if (speed) {
       
   285         posInfo.setAttribute(QGeoPositionInfo::GroundSpeed, speed);
       
   286     }
       
   287     
       
   288     if (track) {
       
   289         posInfo.setAttribute(QGeoPositionInfo::Direction, track);
       
   290     }
       
   291     
       
   292     if (climb) {
       
   293         posInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, climb);        
       
   294     }
       
   295 
       
   296     // Only positions with time (3D) are provided.
       
   297     if (time) {
       
   298         posInfo.setTimestamp(QDateTime::fromTime_t(time));
       
   299         return posInfo;
       
   300     }
       
   301 
       
   302     return QGeoPositionInfo();
       
   303 }
       
   304 
       
   305 void LiblocationWrapper::satellitesInViewUpdated(const QList<QGeoSatelliteInfo> &satellites)
       
   306 {
       
   307     satsInView = satellites;
       
   308 }
       
   309 
       
   310 void LiblocationWrapper::satellitesInUseUpdated(const QList<QGeoSatelliteInfo> &satellites)
       
   311 {
       
   312     satsInUse = satellites;
       
   313 }
       
   314 
       
   315 QList<QGeoSatelliteInfo> LiblocationWrapper::satellitesInView()
       
   316 {
       
   317     return satsInView;
       
   318 }
       
   319 
       
   320 QList<QGeoSatelliteInfo> LiblocationWrapper::satellitesInUse()
       
   321 {
       
   322     return satsInUse;
       
   323 }
       
   324 
       
   325 void LiblocationWrapper::start() {
       
   326     startcounter++;
       
   327 
       
   328     if ((locationState & LiblocationWrapper::Inited) &&
       
   329         !(locationState & LiblocationWrapper::Started)) {
       
   330         if (!errorHandlerId) {
       
   331             errorHandlerId =
       
   332                 g_signal_connect(G_OBJECT(locationControl), "error-verbose",
       
   333                                  G_CALLBACK(&locationError), 
       
   334                                  static_cast<void*>(this));
       
   335         }
       
   336 
       
   337         if (!posChangedId) {
       
   338             posChangedId =
       
   339                 g_signal_connect(G_OBJECT(locationDevice), "changed",
       
   340                                  G_CALLBACK(&locationChanged), 
       
   341                                  static_cast<void*>(this));
       
   342         }
       
   343 
       
   344         location_gpsd_control_start(locationControl);
       
   345         
       
   346         locationState |= LiblocationWrapper::Started;
       
   347         locationState &= ~LiblocationWrapper::Stopped;
       
   348     }
       
   349 }
       
   350 
       
   351 void LiblocationWrapper::stop() {
       
   352     startcounter--;
       
   353 
       
   354     if (startcounter > 0)
       
   355         return;
       
   356     
       
   357     if ((locationState & (LiblocationWrapper::Started |
       
   358                           LiblocationWrapper::Inited)) &&
       
   359         !(locationState & LiblocationWrapper::Stopped)) {
       
   360         if (errorHandlerId)
       
   361             g_signal_handler_disconnect(G_OBJECT(locationControl), 
       
   362                                         errorHandlerId);
       
   363         if (posChangedId)
       
   364             g_signal_handler_disconnect(G_OBJECT(locationDevice), 
       
   365                                         posChangedId);
       
   366         errorHandlerId = 0;
       
   367         posChangedId = 0;
       
   368         startcounter = 0;
       
   369         location_gpsd_control_stop(locationControl);
       
   370 
       
   371         locationState &= ~LiblocationWrapper::Started;
       
   372         locationState |= LiblocationWrapper::Stopped;
       
   373     }
       
   374 }
       
   375 
       
   376 bool LiblocationWrapper::isActive() {
       
   377     if (locationState & LiblocationWrapper::Started)
       
   378         return true;
       
   379     else
       
   380         return false;
       
   381 }
       
   382 
       
   383 #include "moc_liblocationwrapper_p.cpp"
       
   384 QTM_END_NAMESPACE
       
   385