summaryrefslogtreecommitdiff
path: root/src/plugins/position/blackberry/qgeopositioninfosource_bb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/position/blackberry/qgeopositioninfosource_bb.cpp')
-rw-r--r--src/plugins/position/blackberry/qgeopositioninfosource_bb.cpp1268
1 files changed, 0 insertions, 1268 deletions
diff --git a/src/plugins/position/blackberry/qgeopositioninfosource_bb.cpp b/src/plugins/position/blackberry/qgeopositioninfosource_bb.cpp
deleted file mode 100644
index ae58c7b7..00000000
--- a/src/plugins/position/blackberry/qgeopositioninfosource_bb.cpp
+++ /dev/null
@@ -1,1268 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 - 2013 BlackBerry Limited. All rights reserved.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtPositioning module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** 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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qgeopositioninfosource_bb_p.h"
-#include "locationmanagerutil_bb.h"
-
-#ifndef BB_TEST_BUILD
-# include <bb/PpsObject>
-#else
-# include "../tests/include/PpsObjectStuntDouble.hpp"
-#endif
-
-extern "C" {
-#include <wmm/wmm.h>
-}
-
-#include <location_manager.h>
-
-#include <QMap>
-#include <QVariantMap>
-#include <QByteArray>
-#include <QtDebug>
-#include <QStringList>
-
-#include <errno.h>
-
-///////////////////////////
-//
-// local variables/functions
-//
-///////////////////////////
-
-namespace global
-{
-
-// Currently the default behavior for Location Manager is simply to set a constant default
-// interval. 5 sec has been chosen as a compromise between timely updates and conserving power.
-static const int defaultPositionUpdatePeriod = 5;
-
-} // namespace global
-
-namespace
-{
-
-// map the Location Manager reply error codes to the PositionErrorCode enum values.
-QMap<int, bb::location::PositionErrorCode::Type> createIntToPositionErrorCodeMap()
-{
- QMap<int, bb::location::PositionErrorCode::Type> map;
-
- map.insert(0, bb::location::PositionErrorCode::None);
- map.insert(1, bb::location::PositionErrorCode::FatalDisabled);
- map.insert(2, bb::location::PositionErrorCode::FatalNoLastKnownPosition);
- map.insert(3, bb::location::PositionErrorCode::FatalInsufficientProviders);
- map.insert(4, bb::location::PositionErrorCode::FatalInvalidRequest);
- map.insert(5, bb::location::PositionErrorCode::FatalUnknown);
- map.insert(6, bb::location::PositionErrorCode::FatalPermission);
- map.insert(0x10000, bb::location::PositionErrorCode::WarnTimeout);
- map.insert(0x10001, bb::location::PositionErrorCode::WarnLostTracking);
- map.insert(0x10002, bb::location::PositionErrorCode::WarnStationary);
-
- return map;
-}
-
-const QMap<int, bb::location::PositionErrorCode::Type> intToPositionErrorCodeMap =
- createIntToPositionErrorCodeMap();
-
-bool fatalError(bb::location::PositionErrorCode::Type code)
-{
- if ( code == bb::location::PositionErrorCode::FatalDisabled
- || code == bb::location::PositionErrorCode::FatalNoLastKnownPosition
- || code == bb::location::PositionErrorCode::FatalInsufficientProviders
- || code == bb::location::PositionErrorCode::FatalInvalidRequest
- || code == bb::location::PositionErrorCode::FatalUnknown
- || code == bb::location::PositionErrorCode::FatalPermission ) {
- return true;
- }
- return false;
-}
-
-// map the PositionErrorCode enum values to the Qt5 QGeoPositionInfoSource::Error enum values.
-QMap<bb::location::PositionErrorCode::Type, QGeoPositionInfoSource::Error>
- createPositionErrorCodeToErrorMap()
-{
- QMap<bb::location::PositionErrorCode::Type, QGeoPositionInfoSource::Error> map;
-
- map.insert(bb::location::PositionErrorCode::FatalDisabled,
- QGeoPositionInfoSource::ClosedError);
- map.insert(bb::location::PositionErrorCode::FatalNoLastKnownPosition,
- QGeoPositionInfoSource::UnknownSourceError);
- map.insert(bb::location::PositionErrorCode::FatalInsufficientProviders,
- QGeoPositionInfoSource::UnknownSourceError);
- map.insert(bb::location::PositionErrorCode::FatalInvalidRequest,
- QGeoPositionInfoSource::UnknownSourceError);
- map.insert(bb::location::PositionErrorCode::FatalUnknown,
- QGeoPositionInfoSource::UnknownSourceError);
- map.insert(bb::location::PositionErrorCode::FatalPermission,
- QGeoPositionInfoSource::AccessError);
-
- return map;
-}
-
-const QMap<bb::location::PositionErrorCode::Type, QGeoPositionInfoSource::Error>
- positionErrorCodeToErrorMap = createPositionErrorCodeToErrorMap();
-
-// map the Location Manager provider names to the QGeoPositionInfoSource positioning methods
-QMap<QGeoPositionInfoSource::PositioningMethods, QString> createPositioningMethodsToProviderMap()
-{
- QMap<QGeoPositionInfoSource::PositioningMethods, QString> map;
-
- map.insert(QGeoPositionInfoSource::SatellitePositioningMethods, QString("gnss"));
- map.insert(QGeoPositionInfoSource::NonSatellitePositioningMethods, QString("network"));
- map.insert(QGeoPositionInfoSource::AllPositioningMethods, QString("hybrid"));
-
- return map;
-}
-
-const QMap<QGeoPositionInfoSource::PositioningMethods, QString>
- positioningMethodsToProviderMap = createPositioningMethodsToProviderMap();
-
-// list of valid strings for the Location Manager reset types
-QStringList createValidResetTypesList()
-{
- QStringList list;
- list.append("cold");
- list.append("warm");
- list.append("hot");
- list.append("factory");
- list.append("ee_data");
- list.append("almanac");
- list.append("ephemeris");
-
- return list;
-}
-
-const QStringList validResetTypes = createValidResetTypesList();
-
-void printGetGeomagneticFieldInputs(const wmm_location_t &location, const struct tm &date)
-{
- qWarning() << "location = ("
- << location.latitude_deg
- << ","
- << location.longitude_deg
- << ","
- << location.altitude_meters
- << ")";
- qWarning() << "date = (" << date.tm_sec <<
- "," << date.tm_min <<
- "," << date.tm_hour <<
- "," << date.tm_mday <<
- "," << date.tm_mon <<
- "," << date.tm_year <<
- "," << date.tm_wday <<
- "," << date.tm_yday <<
- "," << date.tm_isdst <<
-#ifndef BB_TEST_BUILD
-// the following fields are not present on host (at least Win32)
- "," << date.tm_gmtoff <<
- "," << date.tm_zone <<
-#endif
- ")";
-}
-
-bool magneticDeclination(double *declination, const QGeoPositionInfo &position)
-{
- if (!declination)
- return false;
-
- wmm_location_t location;
- struct tm date;
- wmm_geomagnetic_field_t field;
-
- location.latitude_deg = position.coordinate().latitude();
- location.longitude_deg = position.coordinate().longitude();
- if (position.coordinate().type() == QGeoCoordinate::Coordinate3D)
- location.altitude_meters = position.coordinate().altitude();
- else
- location.altitude_meters = 0.0;
-
- time_t time = (time_t)position.timestamp().toTime_t();
-#ifdef BB_TEST_BUILD
- // since gmtime_r() is not defined on host (at least Win32) risk reentrant side effects on the
- // returned data.
- struct tm *pDate = gmtime(&time);
- if (pDate == NULL) {
- qWarning() << "QGeoPositionInfoSourceBbPrivate.cpp:magneticDeclination(): "
- "gmtime() returned NULL";
- return false;
- }
- date = *pDate;
-#else
- if (gmtime_r(&time, &date) == NULL) {
- qWarning() << "QGeoPositionInfoSourceBbPrivate.cpp:magneticDeclination(): "
- "gmtime_r() returned NULL";
- return false;
- }
-#endif
-
- switch (wmm_get_geomagnetic_field(&location, &date, &field)) {
- case 0:
- break;
-
- case 1:
- qWarning() << "QGeoPositionInfoSourceBbPrivate.cpp:magneticDeclination(): "
- "wmm_get_geomagnetic_field() returned: inputs limited to model range";
- printGetGeomagneticFieldInputs(location, date);
- break;
-
- case -1:
- default:
- qWarning() << "QGeoPositionInfoSourceBbPrivate.cpp:magneticDeclination(): "
- "wmm_get_geomagnetic_field() returned: error";
- printGetGeomagneticFieldInputs(location, date);
- return false;
- }
-
- *declination = field.declination_deg;
- return true;
-}
-
-QVariantMap populateLastKnownPositionRequest(bool fromSatellitePositioningMethodsOnly)
-{
- QVariantMap map;
- QVariantMap datMap;
-
- if (fromSatellitePositioningMethodsOnly)
- datMap.insert("provider", "gnss");
- else
- datMap.insert("provider", "hybrid");
-
- datMap.insert("last_known", true);
- datMap.insert("period", 0);
-
- map.insert("msg", "location");
- map.insert("id", ::global::libQtLocationId);
- map.insert("dat", datMap);
-
- return map;
-}
-
-// From a QvariantMap representing a location response from the Location Manager fill a
-// QGeoPositionInfo instance intended to be emitted via positionUpdated() signal. Returns true
-// if the position info was successfully populated.
-bool populatePositionInfo(QGeoPositionInfo *position, const QVariantMap &map)
-{
- // populate position
-
- // set the reply dat property, which can be accessed by the user in the slot connected to
- //the positionUpdated() signal
- QVariantMap replyDat = map.value("dat").toMap();
-
- // check for required fields
- if (!replyDat.contains("latitude") || !replyDat.contains("longitude")
- || !replyDat.contains("accuracy")) {
- return false;
- }
-
- // set the lat/long/alt coordinate
- QGeoCoordinate coord;
- coord.setLatitude(replyDat.value("latitude").toDouble());
- coord.setLongitude(replyDat.value("longitude").toDouble());
- if (replyDat.contains("altitude"))
- coord.setAltitude(replyDat.value("altitude").toDouble());
-
- if (!coord.isValid())
- return false;
-
- position->setCoordinate(coord);
-
- // set the time stamp
- QDateTime dateTime;
- dateTime.setTimeSpec(Qt::UTC);
- if (replyDat.contains("utc") && static_cast<int>(replyDat.value("utc").toDouble()) != 0) {
- // utc is msec since epoch (1970-01-01T00:00:00)
- dateTime.setTime_t(qRound((replyDat.value("utc").toDouble() / 1000.0)));
- } else {
- // this relies on the device's clock being accurate
- dateTime = QDateTime::currentDateTimeUtc();
- }
- position->setTimestamp(dateTime);
-
- // attributes
- if (replyDat.contains("heading")) {
- position->setAttribute(QGeoPositionInfo::Direction,
- static_cast<qreal>(replyDat.value("heading").toDouble()));
- } else {
- position->removeAttribute(QGeoPositionInfo::Direction);
- }
-
- if (replyDat.contains("speed")) {
- position->setAttribute(QGeoPositionInfo::GroundSpeed,
- static_cast<qreal>(replyDat.value("speed").toDouble()));
- } else {
- position->removeAttribute(QGeoPositionInfo::GroundSpeed);
- }
-
- if (replyDat.contains("verticalSpeed")) {
- position->setAttribute(QGeoPositionInfo::VerticalSpeed,
- static_cast<qreal>(replyDat.value("verticalSpeed").toDouble()));
- } else {
- position->removeAttribute(QGeoPositionInfo::VerticalSpeed);
- }
-
- if (replyDat.contains("declination")) {
- position->setAttribute(QGeoPositionInfo::MagneticVariation,
- static_cast<qreal>(replyDat.value("declination").toDouble()));
- } else {
- double declination;
-
- if (magneticDeclination(&declination, *position) == true) {
- position->setAttribute(QGeoPositionInfo::MagneticVariation,
- static_cast<qreal>(declination));
- } else {
- position->removeAttribute(QGeoPositionInfo::MagneticVariation);
- }
- }
-
- // replyDat.contains("accuracy") was confirmed above
- position->setAttribute(QGeoPositionInfo::HorizontalAccuracy,
- static_cast<qreal>(replyDat.value("accuracy").toDouble()));
-
- if (replyDat.contains("altitudeAccuracy")) {
- position->setAttribute(QGeoPositionInfo::VerticalAccuracy,
- static_cast<qreal>(replyDat.value("altitudeAccuracy").toDouble()));
- } else {
- position->removeAttribute(QGeoPositionInfo::VerticalAccuracy);
- }
-
- return true;
-}
-
-} // unnamed namespace
-
-///////////////////////////
-//
-// QGeoPositionInfoSourceBbPrivate
-//
-///////////////////////////
-
-// Create a QVariantMap suitable for writing to a PpsObject specifying a location request to the
-// Location Manager. If the request is periodic then the update interval is used. Otherwise 0
-// indicates to the Location Manager that it is a request for a single, immediate location response.
-// singleRequestMsec applies only to the single, immediate location response. It represents the
-// expected location response time, after which it is assumed a timeout response occurs.
-QVariantMap QGeoPositionInfoSourceBbPrivate::populateLocationRequest(bool periodic,
- int singleRequestMsec) const
-{
- Q_Q(const QGeoPositionInfoSourceBb);
-
- QVariantMap map;
- QVariantMap datMap;
-
- int period;
- int responseTime;
- if (periodic) {
- // rounding is performed here because the Location Manager truncates to nearest integer
- period = (q->updateInterval() + 500) / 1000;
- // The Qt MObility API treats a period of 0 as indicating default behavior
- if (period == 0) {
- // specify global::defaultPositionUpdatePeriod as the default behavior for Location
- // Manager
- period = ::global::defaultPositionUpdatePeriod;
- }
- responseTime = qRound(_responseTime);
- } else {
- period = 0;
- responseTime = (singleRequestMsec + 500) / 1000;
- }
-
- // period is the only mandatory field
- datMap.insert("period", period);
-
- if (_accuracy > 0.0)
- datMap.insert("accuracy", _accuracy);
- if (responseTime > 0.0)
- datMap.insert("response_time", responseTime);
-
- // since there is no uninitialized state for bool always specify the background mode
- datMap.insert("background", _canRunInBackground);
-
- QString provider = positioningMethodsToProviderMap.value(q->preferredPositioningMethods());
- if (!provider.isEmpty())
- datMap.insert("provider", provider);
-
- if (!_fixType.isEmpty())
- datMap.insert("fix_type", _fixType);
-
- if (!_appId.isEmpty())
- datMap.insert("app_id", _appId);
-
- if (!_appPassword.isEmpty())
- datMap.insert("app_password", _appPassword);
-
- if (!_pdeUrl.isEmpty())
- datMap.insert("pde_url", _pdeUrl.toEncoded().constData());
-
- if (!_slpUrl.isEmpty())
- datMap.insert("slp_url", _slpUrl.toEncoded().constData());
-
- map.insert("msg", "location");
- map.insert("id", global::libQtLocationId);
- map.insert("dat", datMap);
-
- return map;
-}
-
-QVariantMap QGeoPositionInfoSourceBbPrivate::populateResetRequest() const
-{
- QVariantMap map;
- QVariantMap datMap;
-
- datMap.insert("reset_type", _resetType);
-
- map.insert("msg", "reset");
- map.insert("id", ::global::libQtLocationId);
- map.insert("dat", datMap);
-
- return map;
-}
-
-bool QGeoPositionInfoSourceBbPrivate::requestPositionInfo(bool periodic, int singleRequestMsec)
-{
- // build up the request
- QVariantMap request = populateLocationRequest(periodic, singleRequestMsec);
-
- bb::PpsObject *ppsObject;
- if (periodic)
- ppsObject = _periodicUpdatePpsObject;
- else
- ppsObject = _singleUpdatePpsObject;
-
- bool returnVal = sendRequest(*ppsObject, request);
-#ifndef BB_TEST_BUILD
- if (!returnVal) {
- // test for pps file error
- switch (ppsObject->error()) {
- case EACCES:
- _replyErrorCode = bb::location::PositionErrorCode::FatalPermission;
- _replyErr = "failed";
- _replyErrStr = ppsObject->errorString();
- break;
-
- case EOK:
- _replyErrorCode = bb::location::PositionErrorCode::FatalUnknown;
- _replyErr = "failed";
- _replyErrStr = "Unknown error occurred sending request";
- qWarning() << "QGeoPositionInfoSourceBbPrivate::requestPositionInfo() :"
- << _replyErrStr;
- break;
-
- default:
- _replyErrorCode = bb::location::PositionErrorCode::FatalUnknown;
- _replyErr = "failed";
- _replyErrStr = ppsObject->errorString();
- qWarning() << "QGeoPositionInfoSourceBbPrivate::requestPositionInfo() : "
- "unexpected error, errno ="
- << ppsObject->error()
- << " ("
- << ppsObject->errorString()
- << ")";
- break;
- }
- }
-#endif // !BB_TEST_BUILD
-
- return returnVal;
-}
-
-void QGeoPositionInfoSourceBbPrivate::cancelPositionInfo(bool periodic)
-{
- bb::PpsObject *ppsObject;
- if (periodic)
- ppsObject = _periodicUpdatePpsObject;
- else
- ppsObject = _singleUpdatePpsObject;
-
- (void)sendRequest(*ppsObject, global::cancelRequest);
-}
-
-void QGeoPositionInfoSourceBbPrivate::resetLocationProviders()
-{
- QVariantMap map = populateResetRequest();
- (void)sendRequest(*_periodicUpdatePpsObject, map);
-}
-
-// Get the last known position from the Location Manager. Any error results in the return of an
-// invalid position.
-QGeoPositionInfo QGeoPositionInfoSourceBbPrivate::lastKnownPosition(
- bool fromSatellitePositioningMethodsOnly) const
-{
- QGeoPositionInfo position = QGeoPositionInfo();
- bb::PpsObject ppsObject(global::locationManagerPpsFile);
- QVariantMap lastKnown = populateLastKnownPositionRequest(fromSatellitePositioningMethodsOnly);
-
- if (!ppsObject.open())
- return position;
-
- // Location Manager promises to reply immediately with the last known position or an error.
- ppsObject.setBlocking(true);
-
- if (!sendRequest(ppsObject, lastKnown))
- return position;
-
- if (!receiveReply(&lastKnown, ppsObject))
- return position;
-
- if (!lastKnown.contains("res") || lastKnown.value("res").toString() != "location")
- return position;
-
- // the return value of populatePositionInfo() is ignored since either way position is returned
- // by lastKnownPosition()
- (void)populatePositionInfo(&position, lastKnown);
-
- return position;
-}
-
-// Constructor. Note there are two PpsObjects for handling the two different types of requests that
-// can be simultaneously made and which must be handled independently (apart from both being
-// emitted through the same signal when done-part of Qt Mobility spec.
-QGeoPositionInfoSourceBbPrivate::QGeoPositionInfoSourceBbPrivate(QGeoPositionInfoSourceBb *parent)
- : QObject(parent),
- _startUpdatesInvoked(false),
- _requestUpdateInvoked(false),
- _canEmitPeriodicUpdatesTimeout(true),
- q_ptr(parent),
- _periodicUpdatePpsObject(new bb::PpsObject(global::locationManagerPpsFile, this)),
- _singleUpdatePpsObject(new bb::PpsObject(global::locationManagerPpsFile, this)),
- _sourceError(QGeoPositionInfoSource::NoError),
- _accuracy(0.0),
- _responseTime(0.0),
- _canRunInBackground(false),
- _fixType(QString()),
- _appId(QString()),
- _appPassword(QString()),
- _pdeUrl(QUrl()),
- _slpUrl(QUrl()),
- _replyDat(QVariantMap()),
- _replyErrorCode(bb::location::PositionErrorCode::None),
- _replyErr(QString()),
- _replyErrStr(QString()),
- _resetType(QString())
-{
- // register bb::location::PositionErrorCode::Type so it can be used with QObject::property()
- qRegisterMetaType<bb::location::PositionErrorCode::Type>();
-
- // connect to periodic update PpsObject::readyRead()
- connect(_periodicUpdatePpsObject, SIGNAL(readyRead()), SLOT(receivePeriodicPositionReply()));
-
- // connect to single update PpsObject::readyRead()
- connect(_singleUpdatePpsObject, SIGNAL(readyRead()), SLOT(receiveSinglePositionReply()));
-
- // queued connection to signal updateTimeout()
- connect(this, SIGNAL(queuedUpdateTimeout()), SLOT(emitUpdateTimeout()), Qt::QueuedConnection);
-}
-
-QGeoPositionInfoSourceBbPrivate::~QGeoPositionInfoSourceBbPrivate()
-{
- stopUpdates();
-}
-
-// request periodic updates
-void QGeoPositionInfoSourceBbPrivate::startUpdates()
-{
- // do nothing if periodic updates have already been started
- if (_startUpdatesInvoked)
- return;
-
- // This flag is used to limit emitting the timeout signal to once per each interruption in the
- // periodic updates. Since updates are being started here ensure the flag is set to true.
- _canEmitPeriodicUpdatesTimeout = true;
-
- // build a request and initiate it
- if (requestPositionInfo(true)) {
- _startUpdatesInvoked = true;
- _currentPosition = QGeoPositionInfo();
- } else {
- // With Qt5 the error() signal was introduced. If there are any receivers emit error() else
- // maintain QtMobility behavior.
- _sourceError
- = positionErrorCodeToErrorMap.value(_replyErrorCode,
- QGeoPositionInfoSource::UnknownSourceError);
- Q_Q(QGeoPositionInfoSourceBb);
- if (q->receivers(SIGNAL(error(QGeoPositionInfoSource::Error)))) {
- Q_EMIT ((QGeoPositionInfoSource *)q)->error(_sourceError);
- } else {
- // user is expecting a signal to be emitted, cannot emit positionUpdated() because of
- // error so emit timeout signal. The connection is queued because it is possible for the
- // user to call startUpdates() from within the slot handling the timeout. The queued
- // connection avoids potential infinite recursion.
- Q_EMIT queuedUpdateTimeout();
- }
- }
-}
-
-// stop periodic updates
-void QGeoPositionInfoSourceBbPrivate::stopUpdates()
-{
- // do nothing if periodic updates have not been started
- if (!_startUpdatesInvoked)
- return;
-
- cancelPositionInfo(true);
- _startUpdatesInvoked = false;
- _currentPosition = QGeoPositionInfo();
-
- // close the pps file to ensure readyRead() does not spin in the event that we don't read the
- // reply to the cancel request. Note that open() is done lazily in sendRequest().
- _periodicUpdatePpsObject->close();
-}
-
-// periodic updates have timed out
-void QGeoPositionInfoSourceBbPrivate::periodicUpdatesTimeout()
-{
- // do nothing if periodic updates have not been started
- if (!_startUpdatesInvoked)
- return;
-
- // timeout has occurred, but periodic updates are still active. Ensure the timeout signal is
- // emitted only once per interruption of updates. _canEmitPeriodicUpdatesTimeout is set back
- // to true when the next successful periodic update occurs (see emitPositionUpdated()). This
- // behavior is per the Qt Mobility Location API documentation.
- if (_canEmitPeriodicUpdatesTimeout) {
- _canEmitPeriodicUpdatesTimeout = false;
- emitUpdateTimeout();
- }
-}
-
-// request single update
-void QGeoPositionInfoSourceBbPrivate::requestUpdate(int msec)
-{
- // do nothing if an immediate update has already been requested
- if (_requestUpdateInvoked)
- return;
-
- if (msec) {
- // If it is not possible to update in msec timeout immediately.
- Q_Q(QGeoPositionInfoSourceBb);
- if (msec < q->minimumUpdateInterval()) {
- // The connection is queued because it is possible for the user to call requestUpdate()
- // from within the slot handling the timeout. The queued connection avoids potential
- // infinite recursion.
- Q_EMIT queuedUpdateTimeout();
- return;
- }
- }
-
- if (requestPositionInfo(false, msec)) {
- _requestUpdateInvoked = true;
- } else {
- // With Qt5 the error() signal was introduced. If there are any receivers emit error() else
- // maintain QtMobility behavior.
- _sourceError
- = positionErrorCodeToErrorMap.value(_replyErrorCode,
- QGeoPositionInfoSource::UnknownSourceError);
- Q_Q(QGeoPositionInfoSourceBb);
- if (q->receivers(SIGNAL(error(QGeoPositionInfoSource::Error)))) {
- Q_EMIT ((QGeoPositionInfoSource *)q)->error(_sourceError);
- } else {
- // user is expecting a signal to be emitted, cannot emit positionUpdated() because of
- // error so emit timeout signal. The connection is queued because it is possible for the
- // user to call startUpdates() from within the slot handling the timeout. The queued
- // connection avoids potential infinite recursion.
- Q_EMIT queuedUpdateTimeout();
- }
- }
-}
-
-// single update has timed out. This is a slot for the requestUpdate timer
-void QGeoPositionInfoSourceBbPrivate::singleUpdateTimeout()
-{
- _requestUpdateInvoked = false;
-
- emitUpdateTimeout();
-
- if (!_requestUpdateInvoked) {
- // close the pps file to ensure readyRead() does not spin in the event that there are
- // unexpected replies that we don't read. Note that open() is done lazily in sendRequest().
- _singleUpdatePpsObject->close();
- }
-}
-
-// This slot is intended for queued connection to the signal queuedUpdateTimeout(). If an error
-// occurs when an update is requested the error is relayed via updateTimeout() but the connection
-// is queued to avoid potential infinite recursion.
-void QGeoPositionInfoSourceBbPrivate::emitUpdateTimeout()
-{
- Q_Q(QGeoPositionInfoSourceBb);
- Q_EMIT q->updateTimeout();
-}
-
-void QGeoPositionInfoSourceBbPrivate::emitPositionUpdated(const QGeoPositionInfo &update)
-{
- // having successfully received a position update, set _canEmitPeriodicUpdatesTimeout to true,
- // which (re)enables a timeout to be emitted upon any subsequent error in periodic updating.
- _canEmitPeriodicUpdatesTimeout = true;
-
- Q_Q(QGeoPositionInfoSourceBb);
- Q_EMIT q->positionUpdated(update);
-}
-
-bool QGeoPositionInfoSourceBbPrivate::receivePositionReply(bb::PpsObject &ppsObject)
-{
- QVariantMap reply;
- // receiveReply() tests for errors associated with the request being replied to
- if (!receiveReply(&reply, ppsObject)) {
- _replyErrorCode = bb::location::PositionErrorCode::FatalUnknown;
-
- // if there is an error from Location Manager report it so user can access it through the
- // properties when responding to the updateTimeout() signal.
- if (reply.contains("errCode")) {
- int errCode = reply.value("errCode").toInt();
- _replyErrorCode
- = intToPositionErrorCodeMap.value(errCode,
- bb::location::PositionErrorCode::FatalUnknown);
- if (fatalError(_replyErrorCode)) {
- _sourceError
- = positionErrorCodeToErrorMap.value(_replyErrorCode,
- QGeoPositionInfoSource::UnknownSourceError);
- }
-
- if (reply.contains("err")) {
- _replyErr = reply.value("err").toString();
- if (reply.contains("errstr")) {
- _replyErrStr = reply.value("errstr").toString();
- }
- }
- } else {
- _sourceError = QGeoPositionInfoSource::UnknownSourceError;
- }
- return false;
- }
-
- // clear any errors
- _replyErrorCode = bb::location::PositionErrorCode::None;
- _replyErr = QString();
- _replyErrStr = QString();
-
- // check that this is a location reply (could be a reply to another request type, eg. cancel,
- // which is ignored here)
- if (reply.contains("res") && reply.value("res").toString() == "location") {
- // keep the raw LM reply for access via Qt properties.
- _replyDat = reply.value("dat").toMap();
-
- // extract the geo position info from the reply into _currentPosition
- if (populatePositionInfo(&_currentPosition, reply)) {
- emitPositionUpdated(_currentPosition);
- }
- }
-
- return true;
-}
-
-void QGeoPositionInfoSourceBbPrivate::receivePeriodicPositionReply()
-{
- // don't try to receive a reply if periodic updates have not been started. This is
- // necessary because this slot is connected to PpsObject::readyRead() and could be
- // invoked any time the pps file is updated by the server. Under error conditions
- // this would otherwise lead to a circular calling sequence: receive, timeout due to
- // error, cancel, receive...
- if (!_startUpdatesInvoked)
- return;
-
- if (!receivePositionReply(*_periodicUpdatePpsObject)) {
- Q_Q(QGeoPositionInfoSourceBb);
- if (fatalError(_replyErrorCode)
- && q->receivers(SIGNAL(error(QGeoPositionInfoSource::Error)))) {
- Q_EMIT ((QGeoPositionInfoSource *)q)->error(_sourceError);
- } else {
- periodicUpdatesTimeout();
- }
- }
-}
-
-void QGeoPositionInfoSourceBbPrivate::receiveSinglePositionReply()
-{
- // don't try to receive a reply if a single update has not been requested. This is
- // necessary because this slot is connected to PpsObject::readyRead() and could be
- // invoked any time the pps file is updated by the server. Under error conditions
- // this would otherwise lead to a circular calling sequence: receive, timeout due to
- // error, cancel, receive...
- if (!_requestUpdateInvoked)
- return;
-
- // clear this before calling receivePositionReply() which can emit the positionUpdated()
- // signal. It is possible to call requestUpdate() in the slot connected to
- // positionUpdated() so for requestUpdate() to work _requestUpdateInvoked must be false
- _requestUpdateInvoked = false;
-
- if (!receivePositionReply(*_singleUpdatePpsObject)) {
- Q_Q(QGeoPositionInfoSourceBb);
- if (fatalError(_replyErrorCode)
- && q->receivers(SIGNAL(error(QGeoPositionInfoSource::Error)))) {
- Q_EMIT ((QGeoPositionInfoSource *)q)->error(_sourceError);
- } else {
- singleUpdateTimeout();
- }
- }
-
- if (!_requestUpdateInvoked) {
- // close the pps file to ensure readyRead() does not spin in the event that there are
- // unexpected replies that we don't read. Note that open() is done lazily in sendRequest().
- _singleUpdatePpsObject->close();
- }
-}
-
-///////////////////////////
-//
-// QGeoPositionInfoSourceBb
-//
-///////////////////////////
-
-/*!
- \class QGeoPositionInfoSourceBb
- \brief The QGeoPositionInfoSourceBb class is for the distribution of positional updates obtained
- from the underlying Qnx Location Manager.
-
- QGeoPositionInfoSourceBb is a subclass of QGeoPositionInfoSource. The static function
- QGeoPositionInfoSource::createDefaultSource() creates a default
- position source that is appropriate for the platform, if one is available. On BB10 this is
- a QGeoPositionInfoSourceBb instance.
-
- Users of a QGeoPositionInfoSource subclass can request the current position using
- requestUpdate(), or start and stop regular position updates using
- startUpdates() and stopUpdates(). When an update is available,
- positionUpdated() is emitted. The last known position can be accessed with
- lastKnownPosition().
-
- If regular position updates are required, setUpdateInterval() can be used
- to specify how often these updates should be emitted. If no interval is
- specified, updates are simply provided whenever they are available.
- For example:
-
- \code
- // Emit updates every 10 seconds if available
- QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(0);
- if (source)
- source->setUpdateInterval(10000);
- \endcode
-
- To remove an update interval that was previously set, call
- setUpdateInterval() with a value of 0.
-
- Note that the position source may have a minimum value requirement for
- update intervals, as returned by minimumUpdateInterval().
-*/
-
-/*!
- Constructs a QGeoPositionInfoSourceBb instance with the given \a parent
- and \a updateMode.
-*/
-QGeoPositionInfoSourceBb::QGeoPositionInfoSourceBb(QObject *parent)
- : QGeoPositionInfoSource(parent),
- d_ptr(new QGeoPositionInfoSourceBbPrivate(this))
-{
-}
-
-/*!
- Destroys the position source.
-*/
-QGeoPositionInfoSourceBb::~QGeoPositionInfoSourceBb()
-{
-}
-
-/*!
- \reimp
-*/
-void QGeoPositionInfoSourceBb::setUpdateInterval(int msec)
-{
- int interval = msec;
- if (interval != 0)
- interval = qMax(msec, minimumUpdateInterval());
-
- if (interval == updateInterval())
- return;
-
- QGeoPositionInfoSource::setUpdateInterval(interval);
-
- Q_D(QGeoPositionInfoSourceBb);
- if (d->_startUpdatesInvoked) {
- d->stopUpdates();
- d->startUpdates();
- }
-}
-
-/*!
- \reimp
-*/
-void QGeoPositionInfoSourceBb::setPreferredPositioningMethods(PositioningMethods methods)
-{
- PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();
- QGeoPositionInfoSource::setPreferredPositioningMethods(methods);
- if (previousPreferredPositioningMethods == preferredPositioningMethods())
- return;
-
- Q_D(QGeoPositionInfoSourceBb);
- if (d->_startUpdatesInvoked) {
- d->stopUpdates();
- d->startUpdates();
- }
-}
-
-/*!
- \reimp
-*/
-void QGeoPositionInfoSourceBb::startUpdates()
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->startUpdates();
-}
-
-/*!
- \reimp
-*/
-void QGeoPositionInfoSourceBb::stopUpdates()
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->stopUpdates();
-}
-
-/*!
- \reimp
-*/
-void QGeoPositionInfoSourceBb::requestUpdate(int msec)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->requestUpdate(msec);
-}
-
-/*!
- \reimp
-*/
-QGeoPositionInfo
- QGeoPositionInfoSourceBb::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->lastKnownPosition(fromSatellitePositioningMethodsOnly);
-}
-
-/*!
- \reimp
-*/
-QGeoPositionInfoSource::PositioningMethods
- QGeoPositionInfoSourceBb::supportedPositioningMethods() const
-{
- return AllPositioningMethods;
-}
-
-/*!
- \reimp
-*/
-int QGeoPositionInfoSourceBb::minimumUpdateInterval() const
-{
- return global::minUpdateInterval;
-}
-
-QGeoPositionInfoSource::Error QGeoPositionInfoSourceBb::error() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_sourceError;
-}
-
-// these properties extend QGeoPositionInfoSource allowing use of additional features of the Qnx Location Manager
-
-// the following properties are the fields of the dat parameter of the location request
-
-/*!
- \property QGeoPositionInfoSourceBb::period
- \brief This property specifies the period of the location request, in seconds. A value of
- '0' indicates a one-time location request.
-*/
-double QGeoPositionInfoSourceBb::period() const
-{
- // convert from msec to sec
- return updateInterval() / 1000.0;
-}
-
-void QGeoPositionInfoSourceBb::setPeriod(double period)
-{
- // convert from sec to msec, round to nearest msec
- setUpdateInterval(qRound(static_cast<qreal>(period * 1000.0)));
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::accuracy
- \brief This property specifies the desired accuracy of the fix, in meters. A value of '0'
- disables accuracy criteria.
-*/
-double QGeoPositionInfoSourceBb::accuracy() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_accuracy;
-}
-
-void QGeoPositionInfoSourceBb::setAccuracy(double accuracy)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->_accuracy = accuracy;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::responseTime
- \brief This property specifies the desired response time of the fix, in seconds. A value of
- '0' disables response time criteria.
-*/
-double QGeoPositionInfoSourceBb::responseTime() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_responseTime;
-}
-
-void QGeoPositionInfoSourceBb::setResponseTime(double responseTime)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->_responseTime = responseTime;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::canRunInBackground
- \brief This property determines whether or not requests are allowed to run with the device
- in standby (i.e. screen off)
-*/
-bool QGeoPositionInfoSourceBb::canRunInBackground() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_canRunInBackground;
-}
-
-void QGeoPositionInfoSourceBb::setCanRunInBackground(bool canRunInBackground)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->_canRunInBackground = canRunInBackground;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::provider
- \brief This property specifies the location provider you wish to use (hybrid, gnss,
- network).
-*/
-QString QGeoPositionInfoSourceBb::provider() const
-{
- return positioningMethodsToProviderMap.value(preferredPositioningMethods());
-}
-
-void QGeoPositionInfoSourceBb::setProvider(const QString &provider)
-{
- setPreferredPositioningMethods(positioningMethodsToProviderMap.key(provider));
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::fixType
- \brief This property specifies the fix type you wish to use (best, gps_ms_based,
- gps_ms_assisted, gps_autonomous, cellsite, wifi).
-*/
-QString QGeoPositionInfoSourceBb::fixType() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_fixType;
-}
-
-void QGeoPositionInfoSourceBb::setFixType(const QString &fixType)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->_fixType = fixType;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::appId
- \brief This property specifies a special application id.
-*/
-QString QGeoPositionInfoSourceBb::appId() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_appId;
-}
-
-void QGeoPositionInfoSourceBb::setAppId(const QString &appId)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->_appId = appId;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::appPassword
- \brief This property specifies a special application password, goes with appId above.
-*/
-QString QGeoPositionInfoSourceBb::appPassword() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_appPassword;
-}
-
-void QGeoPositionInfoSourceBb::setAppPassword(const QString &appPassword)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->_appPassword = appPassword;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::pdeUrl
- \brief This property specifies the PDE URL (i.e. tcp://user:pass@address.dom:1234).
-*/
-QUrl QGeoPositionInfoSourceBb::pdeUrl() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_pdeUrl;
-}
-
-void QGeoPositionInfoSourceBb::setPdeUrl(const QUrl &pdeUrl)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->_pdeUrl = pdeUrl;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::slpUrl
- \brief This property specifies the SLP URL (i.e. tcp://user:pass@address.dom:1234).
-*/
-QUrl QGeoPositionInfoSourceBb::slpUrl() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_slpUrl;
-}
-
-void QGeoPositionInfoSourceBb::setSlpUrl(const QUrl &slpUrl)
-{
- Q_D(QGeoPositionInfoSourceBb);
- d->_slpUrl = slpUrl;
-}
-
-// the following read-only properties are the fields of the Location Manager generic reply
-
-/*!
- \property QGeoPositionInfoSourceBb::replyDat
- \brief This property specifies the object containing the reply data (such as latitude,
- longitude, satellites, etc). If the replyErr is not empty then replyDat may be empty or
- stale. replyDat is expected to be consumed in the slot connected to the positionUpdated()
- signal, otherwise its contents are undefined.
-*/
-QVariantMap QGeoPositionInfoSourceBb::replyDat() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_replyDat;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::replyErrorCode
- \brief If not empty this property indicates that an error has occurred, and identifies the
- error.
-
- Possible values are:
-
- Code | Description
- None | No error
- FatalDisabled | Location services is disabled
- FatalNoLastKnownPosition | There is no last known position on the device
- FatalInsufficientProviders | There are insufficient available location technology providers
- to process your request
- FatalInvalidRequest | One or more of the request parameters are invalid.
- WarnTimeout | A timeout has occurred while processing your request. The request will
- continue until your location is obtained
- WarnLostTracking | The location fix has been lost due to insufficient coverage. The request
- will continue until your location is reacquired
- WarnStationary | The device is stationary. No further updates until the device resumes
- movement
-
- replyErrorCode is expected to be consumed in the slot connected to the updateTimeout()
- signal, which is emitted when an error is detected. Otherwise its contents are undefined.
-*/
-bb::location::PositionErrorCode::Type QGeoPositionInfoSourceBb::replyErrorCode() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_replyErrorCode;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::replyErr
- \brief If not empty this property indicates that an error has occurred, and identifies the
- error. replyErr is expected to be consumed in the slot connected to the updateTimeout()
- signal, which is emitted when an error is detected. Otherwise its contents are undefined.
-*/
-QString QGeoPositionInfoSourceBb::replyErr() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_replyErr;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::replyErrStr
- \brief This property is not empty if and only if the replyErr parameter is present, it
- describes the error. replyErrStr is expected to be consumed in the slot connected to the
- updateTimeout() signal, which is emitted when an error is detected. Otherwise its contents
- are undefined.
-*/
-QString QGeoPositionInfoSourceBb::replyErrStr() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_replyErrStr;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::locationServicesEnabled
- \brief This property indicates whether the location services are enabled or not. If
- location services are disabled then no position updates will occur. The user must enable
- location services through the Settings app before any position updates will be available.
-*/
-bool QGeoPositionInfoSourceBb::locationServicesEnabled() const
-{
- bool locationEnabled = false;
- if (location_manager_get_status(&locationEnabled) != 0) {
- qWarning() << "QGeoPositionInfoSourceBb::locationServicesEnabled() : "
- "call to location_manager_get_status() failed.";
- }
- return locationEnabled;
-}
-
-/*!
- \property QGeoPositionInfoSourceBb::reset
- \brief By setting this property a reset of all location providers is requested through the
- Location Manager. The value of reset specifies the type of reset to be performed. Valid
- reset types are "cold", "warm", "hot", and "factory". The reset is not actually carried out
- until position updates are restarted. The current value of this property, i.e.
- property("reset"), is not particularly useful, it is simply the reset type corresponding to
- the last time setProperty("reset", resetType) was called. A Qt property must have a READ
- method, hence the reason for defining resetType().
-*/
-QString QGeoPositionInfoSourceBb::resetType() const
-{
- Q_D(const QGeoPositionInfoSourceBb);
- return d->_resetType;
-}
-
-void QGeoPositionInfoSourceBb::requestReset(const QString &resetType)
-{
- if (validResetTypes.contains(resetType)) {
- Q_D(QGeoPositionInfoSourceBb);
- d->_resetType = resetType;
- d->resetLocationProviders();
- }
-}