summaryrefslogtreecommitdiff
path: root/agents/notificationconn.cc
diff options
context:
space:
mode:
Diffstat (limited to 'agents/notificationconn.cc')
-rw-r--r--agents/notificationconn.cc190
1 files changed, 190 insertions, 0 deletions
diff --git a/agents/notificationconn.cc b/agents/notificationconn.cc
new file mode 100644
index 0000000..bfe719b
--- /dev/null
+++ b/agents/notificationconn.cc
@@ -0,0 +1,190 @@
+#include <QtCore/QDebug>
+#include <QtCore/QTimer>
+#include <QtCore/QFile>
+
+#include "sappeer.h"
+#include "endianhelpers.h"
+#include "notificationconn.h"
+
+#if SAILFISH
+#include "libwatchfish/notificationmonitor.h"
+#include "libwatchfish/notification.h"
+
+static watchfish::NotificationMonitor *monitor = 0;
+#endif
+
+NotificationConn::Notification::Notification()
+ : type(NotificationPopup), sequenceNumber(0), urgent(false),
+ applicationId(0), category(0),
+ count(0), sender(0),
+ notificationId(-1)
+{
+}
+
+NotificationConn::NotificationConn(SAPConnection *conn, QObject *parent)
+ : QObject(parent), _conn(conn), _socket(conn->getSocket(104))
+{
+ connect(_conn, SIGNAL(disconnected()), SLOT(deleteLater()));
+ connect(_conn, SIGNAL(destroyed()), SLOT(deleteLater()));
+ Q_ASSERT(_socket);
+ connect(_socket, SIGNAL(connected()), SLOT(handleConnected()));
+ connect(_socket, SIGNAL(messageReceived()), SLOT(handleMessageReceived()));
+}
+
+QByteArray NotificationConn::packNotification(const Notification &n)
+{
+ QByteArray data;
+
+ append<quint8>(data, 0x10 | n.type);
+ append<quint16>(data, n.sequenceNumber | (n.urgent ? 0x4000 : 0));
+
+ append<quint16>(data, n.applicationId);
+ append<quint8>(data, n.category);
+
+ int attributeCount = 0;
+
+ // Let's count attributes first
+ if (!n.packageName.isEmpty()) attributeCount++;
+ if (n.count >= 0) attributeCount++;
+ if (!n.title.isEmpty()) attributeCount++;
+ if (n.time.isValid()) attributeCount++;
+ if (n.sender >= 0) attributeCount++;
+ if (!n.body.isEmpty()) attributeCount++;
+ if (!n.thumbnail.isEmpty()) attributeCount++;
+ if (!n.applicationName.isEmpty()) attributeCount++;
+ // TODO if (n.openInHost) attributeCount++;
+ //if (n.openInWatch) attributeCount++;
+ if (n.notificationId != -1) attributeCount++;
+
+ append<quint8>(data, attributeCount);
+
+ if (n.time.isValid()) {
+ append<quint32>(data, (NotificationTime << 24) | sizeof(qint64));
+ append<qint64>(data, n.time.toMSecsSinceEpoch());
+ }
+ if (!n.thumbnail.isEmpty()) {
+ append<quint32>(data, (NotificationThumbnail << 24) | n.thumbnail.size());
+ data.append(n.thumbnail);
+ }
+ if (!n.applicationName.isEmpty()) {
+ QByteArray str = n.applicationName.toUtf8();
+ append<quint32>(data, (NotificationApplicationName << 24) | str.length());
+ data.append(str);
+ }
+ if (!n.packageName.isEmpty()) {
+ QByteArray str = n.packageName.toUtf8();
+ append<quint32>(data, (NotificationPackageName << 24) | str.length());
+ data.append(str);
+ }
+ if (!n.title.isEmpty()) {
+ QByteArray str = n.title.toUtf8();
+ append<quint32>(data, (NotificationTitle << 24) | str.length());
+ data.append(str);
+ }
+ if (!n.body.isEmpty()) {
+ QByteArray str = n.body.toUtf8();
+ append<quint32>(data, (NotificationBody << 24) | str.length());
+ data.append(str);
+ }
+ if (n.count >= 0) {
+ append<quint32>(data, (NotificationCount << 24) | sizeof(quint16));
+ append<quint16>(data, n.count);
+ }
+ if (n.sender >= 0) {
+ append<quint32>(data, (NotificationSender << 24) | sizeof(quint16));
+ append<quint16>(data, n.sender);
+ }
+ if (n.notificationId != -1) {
+ append<quint32>(data, (NotificationId << 24) | sizeof(quint32));
+ append<quint32>(data, n.notificationId);
+ }
+
+ return data;
+}
+
+void NotificationConn::sendNotification(const Notification &n)
+{
+ QByteArray packet = packNotification(n);
+
+ qDebug() << packet.toHex();
+
+ _socket->send(packet);
+}
+
+void NotificationConn::handleConnected()
+{
+ qDebug() << "NotificationManager socket now connected!";
+
+#if SAILFISH
+ if (!monitor) {
+ monitor = new watchfish::NotificationMonitor;
+ }
+ connect(monitor, &watchfish::NotificationMonitor::notification,
+ this, &NotificationConn::handleNotification);
+#else
+ QTimer::singleShot(2000, this, SLOT(performTest()));
+#endif
+}
+
+void NotificationConn::handleMessageReceived()
+{
+ QByteArray data = _socket->receive();
+
+ qDebug() << "Got notif msg" << data.toHex();
+
+ // TODO Seems that we receive the notification ID that we should act upon.
+}
+
+#if SAILFISH
+void NotificationConn::handleNotification(watchfish::Notification *wfn)
+{
+ if (wfn->transient()) {
+ // Ignore this notification
+ return;
+ }
+
+ QString sender = wfn->sender();
+ short applicationId = _knownSenders.value(sender, 0);
+ if (!applicationId) {
+ applicationId = _knownSenders.size() + 1;
+ _knownSenders.insert(sender, applicationId);
+ }
+
+ Notification n;
+ n.sequenceNumber = ++_lastSeqNumber;
+ n.type = NotificationPopup;
+ n.time = wfn->timestamp();
+ n.title = wfn->summary();
+ n.packageName = sender;
+ n.applicationName = sender;
+ n.body = wfn->body();
+ n.sender = 0;
+ n.count = 0; // TODO figure this out
+ n.category = 0;
+ n.applicationId = applicationId;
+ n.notificationId = ++_lastNotifId;
+
+ sendNotification(n);
+}
+#endif
+
+void NotificationConn::performTest()
+{
+ qDebug() << "Performing notif test";
+
+ Notification n;
+ n.sequenceNumber = ++_lastSeqNumber;
+ n.type = NotificationPopup;
+ n.time = QDateTime::currentDateTime();
+ n.title = "A title";
+ n.packageName = "com.example.package";
+ n.applicationName = "Example package";
+ n.body = "A long body";
+ n.sender = 0;
+ n.count = 13;
+ n.category = 0;
+ n.applicationId = 0xc2d7;
+ n.notificationId = ++_lastNotifId;
+
+ sendNotification(n);
+}