diff options
| author | Javier <dev.git@javispedro.com> | 2014-12-04 01:21:32 +0100 |
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2014-12-04 01:21:32 +0100 |
| commit | 8722bee52922f8c6707103795fdf69f9ed7d0240 (patch) | |
| tree | d8da8ea953f606abd05a87f6910104e6c7a848b1 | |
| parent | 1b920c3c0593f6810dd900c882e4760cbbbeeb56 (diff) | |
add stub geolocation API
| -rw-r--r-- | daemon/daemon.pro | 2 | ||||
| -rw-r--r-- | daemon/jskitmanager.cpp | 7 | ||||
| -rw-r--r-- | daemon/jskitmanager.h | 2 | ||||
| -rw-r--r-- | daemon/jskitobjects.cpp | 93 | ||||
| -rw-r--r-- | daemon/jskitobjects.h | 43 |
5 files changed, 146 insertions, 1 deletions
diff --git a/daemon/daemon.pro b/daemon/daemon.pro index 3306541..0c4154b 100644 --- a/daemon/daemon.pro +++ b/daemon/daemon.pro @@ -4,7 +4,7 @@ CONFIG += console CONFIG += link_pkgconfig QT -= gui -QT += bluetooth dbus contacts gui qml +QT += bluetooth dbus contacts gui qml positioning PKGCONFIG += mlite5 icu-i18n CONFIG += c++11 diff --git a/daemon/jskitmanager.cpp b/daemon/jskitmanager.cpp index 7bf8cdc..70ea4bd 100644 --- a/daemon/jskitmanager.cpp +++ b/daemon/jskitmanager.cpp @@ -103,6 +103,7 @@ void JSKitManager::startJsApp() _jspebble = new JSKitPebble(_curApp, this); _jsconsole = new JSKitConsole(this); _jsstorage = new JSKitLocalStorage(_curApp.uuid(), this); + _jsgeo = new JSKitGeolocation(this); logger()->debug() << "starting JS app"; @@ -116,6 +117,10 @@ void JSKitManager::startJsApp() windowObj.setProperty("localStorage", globalObj.property("localStorage")); globalObj.setProperty("window", windowObj); + QJSValue navigatorObj = _engine->newObject(); + navigatorObj.setProperty("geolocation", _engine->newQObject(_jsgeo)); + globalObj.setProperty("navigator", navigatorObj); + _engine->evaluate("function XMLHttpRequest() { return Pebble.createXMLHttpRequest(); }"); QFile scriptFile(_curApp.path() + "/pebble-js-app.js"); @@ -151,4 +156,6 @@ void JSKitManager::stopJsApp() _jsstorage = 0; delete _jspebble; _jspebble = 0; + delete _jsgeo; + _jsgeo = 0; } diff --git a/daemon/jskitmanager.h b/daemon/jskitmanager.h index 07ecec1..1f842b7 100644 --- a/daemon/jskitmanager.h +++ b/daemon/jskitmanager.h @@ -8,6 +8,7 @@ class JSKitPebble; class JSKitConsole; class JSKitLocalStorage; +class JSKitGeolocation; class JSKitManager : public QObject { @@ -48,6 +49,7 @@ private: QPointer<JSKitPebble> _jspebble; QPointer<JSKitConsole> _jsconsole; QPointer<JSKitLocalStorage> _jsstorage; + QPointer<JSKitGeolocation> _jsgeo; }; #endif // JSKITMANAGER_H diff --git a/daemon/jskitobjects.cpp b/daemon/jskitobjects.cpp index 728daf7..3b4584b 100644 --- a/daemon/jskitobjects.cpp +++ b/daemon/jskitobjects.cpp @@ -316,3 +316,96 @@ void JSKitXMLHttpRequest::handleReplyError(QNetworkReply::NetworkError code) } } } + +JSKitGeolocation::JSKitGeolocation(JSKitManager *mgr) + : QObject(mgr), _mgr(mgr), _source(0), _lastWatchId(0) +{ + +} + +void JSKitGeolocation::getCurrentPosition(const QJSValue &successCallback, const QJSValue &errorCallback, const QVariantMap &options) +{ + logger()->debug() << Q_FUNC_INFO; + setupWatcher(successCallback, errorCallback, options, true); +} + +int JSKitGeolocation::watchPosition(const QJSValue &successCallback, const QJSValue &errorCallback, const QVariantMap &options) +{ + logger()->debug() << Q_FUNC_INFO; + return setupWatcher(successCallback, errorCallback, options, false); +} + +void JSKitGeolocation::clearWatch(int watchId) +{ + logger()->debug() << Q_FUNC_INFO; +} + +void JSKitGeolocation::handleError(QGeoPositionInfoSource::Error error) +{ + logger()->debug() << Q_FUNC_INFO; +} + +void JSKitGeolocation::handlePosition(const QGeoPositionInfo &pos) +{ + logger()->debug() << Q_FUNC_INFO; +} + +void JSKitGeolocation::handleTimeout() +{ + logger()->debug() << Q_FUNC_INFO; +} + +int JSKitGeolocation::setupWatcher(const QJSValue &successCallback, const QJSValue &errorCallback, const QVariantMap &options, bool once) +{ + Watcher watcher; + watcher.successCallback = successCallback; + watcher.errorCallback = errorCallback; + watcher.highAccuracy = options.value("enableHighAccuracy").toBool(); + watcher.timeout = options.value("timeout", 0xFFFFFFFFU).toUInt(); + watcher.maximumAge = options.value("maximumAge", 0).toUInt(); + watcher.once = once; + watcher.watchId = ++_lastWatchId; + + if (!_source) { + _source = QGeoPositionInfoSource::createDefaultSource(this); + connect(_source, static_cast<void (QGeoPositionInfoSource::*)(QGeoPositionInfoSource::Error)>(&QGeoPositionInfoSource::error), + this, &JSKitGeolocation::handleError); + connect(_source, &QGeoPositionInfoSource::positionUpdated, + this, &JSKitGeolocation::handlePosition); + connect(_source, &QGeoPositionInfoSource::updateTimeout, + this, &JSKitGeolocation::handleTimeout); + } + + if (once && watcher.maximumAge > 0) { + QDateTime threshold = QDateTime::currentDateTime().addMSecs(-watcher.maximumAge); + QGeoPositionInfo pos = _source->lastKnownPosition(watcher.highAccuracy); + if (pos.isValid() && pos.timestamp() >= threshold) { + invokeSuccessCallback(watcher, pos); + return -1; + } else if (watcher.timeout == 0) { + invokeErrorCallback(watcher); + return -1; + } + } + + if (once) { + _source->requestUpdate(watcher.timeout); + } else { + // TODO _source->setInterval to the minimum of all watches + _source->startUpdates(); + } + + return watcher.watchId; +} + +void JSKitGeolocation::invokeSuccessCallback(Watcher &watcher, const QGeoPositionInfo &pos) +{ + // TODO +} + +void JSKitGeolocation::invokeErrorCallback(Watcher &watcher) +{ + if (watcher.errorCallback.isCallable()) { + watcher.errorCallback.call(); // TODO this, eventArgs + } +} diff --git a/daemon/jskitobjects.h b/daemon/jskitobjects.h index 849529f..9c9b84e 100644 --- a/daemon/jskitobjects.h +++ b/daemon/jskitobjects.h @@ -4,6 +4,7 @@ #include <QSettings> #include <QNetworkRequest> #include <QNetworkReply> +#include <QGeoPositionInfoSource> #include "jskitmanager.h" class JSKitPebble : public QObject @@ -134,4 +135,46 @@ private: QJSValue _onerror; }; +class JSKitGeolocation : public QObject +{ + Q_OBJECT + LOG4QT_DECLARE_QCLASS_LOGGER + + struct Watcher; + +public: + explicit JSKitGeolocation(JSKitManager *mgr); + + Q_INVOKABLE void getCurrentPosition(const QJSValue &successCallback, const QJSValue &errorCallback = QJSValue(), const QVariantMap &options = QVariantMap()); + Q_INVOKABLE int watchPosition(const QJSValue &successCallback, const QJSValue &errorCallback = QJSValue(), const QVariantMap &options = QVariantMap()); + Q_INVOKABLE void clearWatch(int watchId); + +private slots: + void handleError(const QGeoPositionInfoSource::Error error); + void handlePosition(const QGeoPositionInfo &pos); + void handleTimeout(); + +private: + int setupWatcher(const QJSValue &successCallback, const QJSValue &errorCallback, const QVariantMap &options, bool once); + void invokeSuccessCallback(Watcher &watcher, const QGeoPositionInfo &pos); + void invokeErrorCallback(Watcher &watcher); + +private: + JSKitManager *_mgr; + QGeoPositionInfoSource *_source; + + struct Watcher { + QJSValue successCallback; + QJSValue errorCallback; + int watchId; + bool once; + bool highAccuracy; + uint timeout; + uint maximumAge; + }; + + QList<Watcher> _watches; + int _lastWatchId; +}; + #endif // JSKITMANAGER_P_H |
