From 87de94ea74c68b5ea0a4b125f1745c7449fbe4f1 Mon Sep 17 00:00:00 2001 From: Javier Date: Wed, 3 Dec 2014 01:19:57 +0100 Subject: fix actually setting the configuration, improve xhr support --- app/qml/pages/AppConfigPage.qml | 2 +- daemon/jskitmanager.cpp | 2 ++ daemon/jskitobjects.cpp | 67 ++++++++++++++++++++++++++++++++++++++--- daemon/jskitobjects.h | 11 ++++++- daemon/manager.cpp | 26 ++++++++++++++-- daemon/manager.h | 5 +-- 6 files changed, 100 insertions(+), 13 deletions(-) diff --git a/app/qml/pages/AppConfigPage.qml b/app/qml/pages/AppConfigPage.qml index 8fb31ca..7b969a3 100644 --- a/app/qml/pages/AppConfigPage.qml +++ b/app/qml/pages/AppConfigPage.qml @@ -21,7 +21,7 @@ Page { console.log("appconfig navigation requested to " + request.url); var url = request.url.toString(); if (/^pebblejs:\/\/close/.exec(url)) { - var data = decodeURI(url.substring(17)); + var data = decodeURIComponent(url.substring(17)); console.log("appconfig requesting close; data: " + data); pebbled.setAppConfiguration(uuid, data); pageStack.pop(); diff --git a/daemon/jskitmanager.cpp b/daemon/jskitmanager.cpp index e1e4073..7bf8cdc 100644 --- a/daemon/jskitmanager.cpp +++ b/daemon/jskitmanager.cpp @@ -44,6 +44,8 @@ void JSKitManager::handleWebviewClosed(const QString &result) QJSValue eventObj = _engine->newObject(); eventObj.setProperty("response", _engine->toScriptValue(result)); + logger()->debug() << "webview closed with the following result: " << result; + _jspebble->invokeCallbacks("webviewclosed", QJSValueList({eventObj})); } else { logger()->warn() << "webview closed event, but JS engine is not running"; diff --git a/daemon/jskitobjects.cpp b/daemon/jskitobjects.cpp index a0bc0ba..728daf7 100644 --- a/daemon/jskitobjects.cpp +++ b/daemon/jskitobjects.cpp @@ -40,11 +40,27 @@ void JSKitPebble::sendAppMessage(QJSValue message, QJSValue callbackForAck, QJSV logger()->debug() << "sendAppMessage" << data; _mgr->_appmsg->send(_appInfo.uuid(), data, [this, callbackForAck]() mutable { - logger()->debug() << "Invoking ack callback"; - callbackForAck.call(); + if (callbackForAck.isCallable()) { + logger()->debug() << "Invoking ack callback"; + QJSValue result = callbackForAck.call(); + if (result.isError()) { + logger()->warn() << "error while invoking ACK callback" << callbackForAck.toString() << ":" + << result.toString(); + } + } else { + logger()->debug() << "Ack callback not callable"; + } }, [this, callbackForNack]() mutable { - logger()->debug() << "Invoking nack callback"; - callbackForNack.call(); + if (callbackForNack.isCallable()) { + logger()->debug() << "Invoking nack callback"; + QJSValue result = callbackForNack.call(); + if (result.isError()) { + logger()->warn() << "error while invoking NACK callback" << callbackForNack.toString() << ":" + << result.toString(); + } + } else { + logger()->debug() << "Nack callback not callable"; + } }); } @@ -187,7 +203,10 @@ void JSKitXMLHttpRequest::send(const QString &body) buffer->setData(body.toUtf8()); logger()->debug() << "sending" << _verb << "to" << _request.url() << "with" << body; _reply = _net->sendCustomRequest(_request, _verb.toLatin1(), buffer); - connect(_reply, &QNetworkReply::finished, this, &JSKitXMLHttpRequest::handleReplyFinished); + connect(_reply, &QNetworkReply::finished, + this, &JSKitXMLHttpRequest::handleReplyFinished); + connect(_reply, static_cast(&QNetworkReply::error), + this, &JSKitXMLHttpRequest::handleReplyError); buffer->setParent(_reply); // So that it gets deleted alongside the reply object. } @@ -209,6 +228,26 @@ void JSKitXMLHttpRequest::setOnload(const QJSValue &value) _onload = value; } +QJSValue JSKitXMLHttpRequest::ontimeout() const +{ + return _ontimeout; +} + +void JSKitXMLHttpRequest::setOntimeout(const QJSValue &value) +{ + _ontimeout = value; +} + +QJSValue JSKitXMLHttpRequest::onerror() const +{ + return _onerror; +} + +void JSKitXMLHttpRequest::setOnerror(const QJSValue &value) +{ + _onerror = value; +} + unsigned short JSKitXMLHttpRequest::readyState() const { if (!_reply) { @@ -259,3 +298,21 @@ void JSKitXMLHttpRequest::handleReplyFinished() logger()->debug() << "No onload set"; } } + +void JSKitXMLHttpRequest::handleReplyError(QNetworkReply::NetworkError code) +{ + if (!_reply) { + logger()->info() << "reply error too late"; + return; + } + + logger()->info() << "reply error" << code; + + if (_onerror.isCallable()) { + logger()->debug() << "going to call onerror handler:" << _onload.toString(); + QJSValue result = _onerror.callWithInstance(_mgr->engine()->newQObject(this)); + if (result.isError()) { + logger()->warn() << "JS error on onerror handler:" << result.toString(); + } + } +} diff --git a/daemon/jskitobjects.h b/daemon/jskitobjects.h index 4f000f1..849529f 100644 --- a/daemon/jskitobjects.h +++ b/daemon/jskitobjects.h @@ -17,7 +17,7 @@ public: Q_INVOKABLE void addEventListener(const QString &type, QJSValue function); Q_INVOKABLE void removeEventListener(const QString &type, QJSValue function); - Q_INVOKABLE void sendAppMessage(QJSValue message, QJSValue callbackForAck, QJSValue callbackForNack); + Q_INVOKABLE void sendAppMessage(QJSValue message, QJSValue callbackForAck = QJSValue(), QJSValue callbackForNack = QJSValue()); Q_INVOKABLE void showSimpleNotificationOnPebble(const QString &title, const QString &body); @@ -79,6 +79,8 @@ class JSKitXMLHttpRequest : public QObject LOG4QT_DECLARE_QCLASS_LOGGER Q_PROPERTY(QJSValue onload READ onload WRITE setOnload) + Q_PROPERTY(QJSValue ontimeout READ ontimeout WRITE setOntimeout) + Q_PROPERTY(QJSValue onerror READ onerror WRITE setOnerror) Q_PROPERTY(unsigned short readyState READ readyState NOTIFY readyStateChanged) Q_PROPERTY(unsigned short status READ status NOTIFY statusChanged) Q_PROPERTY(QString responseText READ responseText NOTIFY responseTextChanged) @@ -102,6 +104,10 @@ public: QJSValue onload() const; void setOnload(const QJSValue &value); + QJSValue ontimeout() const; + void setOntimeout(const QJSValue &value); + QJSValue onerror() const; + void setOnerror(const QJSValue &value); unsigned short readyState() const; unsigned short status() const; @@ -114,6 +120,7 @@ signals: private slots: void handleReplyFinished(); + void handleReplyError(QNetworkReply::NetworkError code); private: JSKitManager *_mgr; @@ -123,6 +130,8 @@ private: QNetworkReply *_reply; QByteArray _response; QJSValue _onload; + QJSValue _ontimeout; + QJSValue _onerror; }; #endif // JSKITMANAGER_P_H diff --git a/daemon/manager.cpp b/daemon/manager.cpp index 1fc8a20..6fd47a4 100644 --- a/daemon/manager.cpp +++ b/daemon/manager.cpp @@ -410,7 +410,8 @@ void Manager::onAppClosed(const QUuid &uuid) emit proxy->AppUuidChanged(); } -bool PebbledProxy::SendAppMessage(const QString &uuid, const QVariantMap &data) { +bool PebbledProxy::SendAppMessage(const QString &uuid, const QVariantMap &data) +{ Q_ASSERT(calledFromDBus()); const QDBusMessage msg = message(); setDelayedReply(true); @@ -424,7 +425,8 @@ bool PebbledProxy::SendAppMessage(const QString &uuid, const QVariantMap &data) return false; // D-Bus clients should never see this reply. } -QString PebbledProxy::StartAppConfiguration(const QString &uuid) { +QString PebbledProxy::StartAppConfiguration(const QString &uuid) +{ Q_ASSERT(calledFromDBus()); const QDBusMessage msg = message(); @@ -474,3 +476,23 @@ QString PebbledProxy::StartAppConfiguration(const QString &uuid) { return QString(); // This return value should never be used. } + +void PebbledProxy::SendAppConfigurationData(const QString &uuid, const QString &data) +{ + Q_ASSERT(calledFromDBus()); + const QDBusMessage msg = message(); + + if (manager()->currentAppUuid != uuid) { + sendErrorReply(msg.interface() + ".Error.AppNotRunning", + "The requested app is not currently opened in the watch"); + return; + } + + if (!manager()->js->isJSKitAppRunning()) { + sendErrorReply(msg.interface() + ".Error.JSNotActive", + "The requested app is not a PebbleKit JS application"); + return; + } + + manager()->js->handleWebviewClosed(data); +} diff --git a/daemon/manager.h b/daemon/manager.h index 22382b8..239c212 100644 --- a/daemon/manager.h +++ b/daemon/manager.h @@ -141,10 +141,7 @@ public slots: bool SendAppMessage(const QString &uuid, const QVariantMap &data); QString StartAppConfiguration(const QString &uuid); - - void SendAppConfiguration(const QString &uuid, const QString &data) { - // TODO - } + void SendAppConfigurationData(const QString &uuid, const QString &data); signals: void NameChanged(); -- cgit v1.2.3