summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier S. Pedro <maemo@javispedro.com>2011-09-24 20:52:17 +0200
committerJavier S. Pedro <maemo@javispedro.com>2011-09-24 20:52:17 +0200
commita1ec50943454ba4674c8c5e5d5dadcdbd414b111 (patch)
tree163aed51758c98fa6feec35a344aa8b5095c32e5
parentcba26597f1c09764d37be0d13863ec5d5c340da0 (diff)
downloadsowatch-a1ec50943454ba4674c8c5e5d5dadcdbd414b111.tar.gz
sowatch-a1ec50943454ba4674c8c5e5d5dadcdbd414b111.zip
Incoming phone calls working!
-rw-r--r--ckitcallnotification/ckitcallnotification.cpp52
-rw-r--r--ckitcallnotification/ckitcallnotification.h40
-rw-r--r--ckitcallnotification/ckitcallnotification.pro8
-rw-r--r--ckitcallnotification/ckitcallprovider.cpp34
-rw-r--r--ckitcallnotification/ckitcallprovider.h9
-rw-r--r--libsowatch/notification.cpp8
-rw-r--r--libsowatch/notification.h33
-rw-r--r--libsowatch/notificationprovider.h11
-rw-r--r--libsowatch/watch.h18
-rw-r--r--libsowatch/watchserver.cpp116
-rw-r--r--libsowatch/watchserver.h24
-rw-r--r--meegohandsetnotification/meegohandsetnotification.cpp61
-rw-r--r--meegohandsetnotification/meegohandsetnotification.h37
-rw-r--r--meegohandsetnotification/meegohandsetnotification.pro8
-rw-r--r--meegohandsetnotification/meegohandsetnotificationprovider.cpp19
-rw-r--r--meegohandsetnotification/meegohandsetnotificationprovider.h4
-rw-r--r--meegohandsetnotification/watchnotificationsink.cpp67
-rw-r--r--meegohandsetnotification/watchnotificationsink.h15
-rw-r--r--metawatch/metawatch.cpp165
-rw-r--r--metawatch/metawatch.h20
-rw-r--r--metawatch/uires.qrc5
21 files changed, 566 insertions, 188 deletions
diff --git a/ckitcallnotification/ckitcallnotification.cpp b/ckitcallnotification/ckitcallnotification.cpp
new file mode 100644
index 0000000..72a768e
--- /dev/null
+++ b/ckitcallnotification/ckitcallnotification.cpp
@@ -0,0 +1,52 @@
+#include "ckitcallnotification.h"
+
+using namespace sowatch;
+
+CKitCallNotification::CKitCallNotification(const QString& displayName, QObject *parent) :
+ Notification(parent),
+ _dateTime(QDateTime::currentDateTime()),
+ _displayName(displayName)
+{
+}
+
+Notification::Type CKitCallNotification::type() const
+{
+ return Notification::CallNotification;
+}
+
+uint CKitCallNotification::count() const
+{
+ return 1;
+}
+
+QDateTime CKitCallNotification::dateTime() const
+{
+ return _dateTime;
+}
+
+QString CKitCallNotification::title() const
+{
+ return _displayName;
+}
+
+QString CKitCallNotification::body() const
+{
+ return tr("Incoming call");
+}
+
+void CKitCallNotification::activate()
+{
+ // TODO Actually do something
+}
+
+void CKitCallNotification::clear()
+{
+ // TODO Actually reject the call
+ emit cleared();
+}
+
+void CKitCallNotification::changeDisplayName(const QString &displayName)
+{
+ _displayName = displayName;
+ emit changed();
+}
diff --git a/ckitcallnotification/ckitcallnotification.h b/ckitcallnotification/ckitcallnotification.h
new file mode 100644
index 0000000..10453be
--- /dev/null
+++ b/ckitcallnotification/ckitcallnotification.h
@@ -0,0 +1,40 @@
+#ifndef CKITCALLNOTIFICATION_H
+#define CKITCALLNOTIFICATION_H
+
+#include <sowatch.h>
+
+namespace sowatch
+{
+
+class CKitCallProvider;
+
+class CKitCallNotification : public Notification
+{
+ Q_OBJECT
+public:
+ explicit CKitCallNotification(const QString& displayName, QObject *parent = 0);
+
+ Type type() const;
+ uint count() const;
+ QDateTime dateTime() const;
+ QString title() const;
+ QString body() const;
+
+ void activate();
+ void clear();
+
+signals:
+ void changed();
+ void cleared();
+
+protected:
+ QDateTime _dateTime;
+ QString _displayName;
+ void changeDisplayName(const QString& displayName);
+
+ friend class CKitCallProvider;
+};
+
+}
+
+#endif // CKITCALLNOTIFICATION_H
diff --git a/ckitcallnotification/ckitcallnotification.pro b/ckitcallnotification/ckitcallnotification.pro
index 17bdf8b..2cee7f8 100644
--- a/ckitcallnotification/ckitcallnotification.pro
+++ b/ckitcallnotification/ckitcallnotification.pro
@@ -10,10 +10,12 @@ TEMPLATE = lib
QT += dbus
SOURCES += ckitcallplugin.cpp \
- ckitcallprovider.cpp
+ ckitcallprovider.cpp \
+ ckitcallnotification.cpp
HEADERS += ckitcallplugin.h \
- ckitcallprovider.h
+ ckitcallprovider.h \
+ ckitcallnotification.h
CONFIG += link_pkgconfig
PKGCONFIG += contextsubscriber-1.0
@@ -35,3 +37,5 @@ unix:!symbian {
+
+
diff --git a/ckitcallnotification/ckitcallprovider.cpp b/ckitcallnotification/ckitcallprovider.cpp
index 85f85b2..adcb6d5 100644
--- a/ckitcallnotification/ckitcallprovider.cpp
+++ b/ckitcallnotification/ckitcallprovider.cpp
@@ -1,16 +1,16 @@
#include <QtCore/QtDebug>
#include <contextsubscriber/contextproperty.h>
+#include "ckitcallnotification.h"
#include "ckitcallprovider.h"
using namespace sowatch;
CKitCallProvider::CKitCallProvider(QObject *parent) :
NotificationProvider(parent),
- _inCall(false),
- _activeCall(new ContextProperty("/com/nokia/CallUi/ActiveCall"))
+ _activeCall(new ContextProperty("/com/nokia/CallUi/ActiveCall")),
+ _notification(0)
{
connect(_activeCall, SIGNAL(valueChanged()), SLOT(activeCallChanged()));
- qDebug() << _activeCall->value();
}
CKitCallProvider::~CKitCallProvider()
@@ -18,23 +18,25 @@ CKitCallProvider::~CKitCallProvider()
}
-int CKitCallProvider::getCount(Notification::Type type)
-{
- Q_UNUSED(type);
- return 0;
-}
-
void CKitCallProvider::activeCallChanged()
{
QVariantMap info = _activeCall->value().toMap();
int state = info["state"].toInt();
if (state == 0) {
- // Incoming call, or update to a incoming call
- _inCall = true;
- emit incomingCall(info["displayName"].toString());
- } else if (_inCall) {
- // Call is no longer incoming
- _inCall = false;
- emit endIncomingCall();
+ QString displayName = info["displayName"].toString();
+ // "Incoming call"
+ if (_notification) {
+ _notification->changeDisplayName(displayName);
+ } else {
+ _notification = new CKitCallNotification(displayName, this);
+ emit incomingNotification(_notification);
+ }
+ } else {
+ // Call is either answered, dropped, missed, ..
+ if (_notification) {
+ _notification->clear();
+ _notification->deleteLater();
+ _notification = 0;
+ }
}
}
diff --git a/ckitcallnotification/ckitcallprovider.h b/ckitcallnotification/ckitcallprovider.h
index 49d83a3..1e1d289 100644
--- a/ckitcallnotification/ckitcallprovider.h
+++ b/ckitcallnotification/ckitcallprovider.h
@@ -8,6 +8,8 @@ class ContextProperty;
namespace sowatch
{
+class CKitCallNotification;
+
class CKitCallProvider : public NotificationProvider
{
Q_OBJECT
@@ -15,15 +17,12 @@ public:
explicit CKitCallProvider(QObject *parent = 0);
~CKitCallProvider();
- int getCount(Notification::Type type);
-
signals:
- void incomingCall(const QString &displayName);
- void endIncomingCall();
+ void incomingNotification(Notification *notification);
protected:
- bool _inCall;
ContextProperty *_activeCall;
+ CKitCallNotification *_notification;
protected slots:
void activeCallChanged();
diff --git a/libsowatch/notification.cpp b/libsowatch/notification.cpp
index 55f3e78..b4c97b2 100644
--- a/libsowatch/notification.cpp
+++ b/libsowatch/notification.cpp
@@ -2,12 +2,16 @@
using namespace sowatch;
-Notification::Notification(Type type, const QDateTime& dateTime, QString title, QString body)
- : _type(type), _dateTime(dateTime), _title(title), _body(body)
+Notification::Notification(QObject *parent)
+ : QObject(parent)
{
}
Notification::~Notification()
{
+}
+QImage Notification::image() const
+{
+ return QImage();
}
diff --git a/libsowatch/notification.h b/libsowatch/notification.h
index 7a46ab7..8e58653 100644
--- a/libsowatch/notification.h
+++ b/libsowatch/notification.h
@@ -3,16 +3,21 @@
#include <QtCore/QString>
#include <QtCore/QDateTime>
+#include <QtGui/QImage>
#include "sowatch_global.h"
namespace sowatch
{
-class SOWATCH_EXPORT Notification
+class SOWATCH_EXPORT Notification : public QObject
{
+ Q_OBJECT
+ Q_ENUMS(Type)
+
public:
enum Type {
OtherNotification = 0,
+ CallNotification,
MissedCallNotification,
SmsNotification,
MmsNotification,
@@ -22,19 +27,23 @@ public:
TypeCount
};
- Notification(Type type, const QDateTime& dateTime, QString title, QString body);
- ~Notification();
+ explicit Notification(QObject *parent = 0);
+ virtual ~Notification();
+
+ virtual Type type() const = 0;
+ virtual uint count() const = 0;
+ virtual QDateTime dateTime() const = 0;
+ virtual QString title() const = 0;
+ virtual QString body() const = 0;
+ virtual QImage image() const;
- inline Type type() const { return _type; }
- inline QDateTime dateTime() const { return _dateTime; }
- inline QString title() const { return _title; }
- inline QString body() const { return _body; }
+public slots:
+ virtual void activate() = 0;
+ virtual void clear() = 0;
-protected:
- Type _type;
- QDateTime _dateTime;
- QString _title;
- QString _body;
+signals:
+ void changed();
+ void cleared();
};
}
diff --git a/libsowatch/notificationprovider.h b/libsowatch/notificationprovider.h
index fe835ef..31182f1 100644
--- a/libsowatch/notificationprovider.h
+++ b/libsowatch/notificationprovider.h
@@ -15,17 +15,8 @@ protected:
explicit NotificationProvider(QObject *parent = 0);
virtual ~NotificationProvider();
-public:
- virtual int getCount(Notification::Type type) = 0;
-
signals:
- void notification(const Notification& n);
- void unreadCountChanged(Notification::Type type);
-
- void weatherUpdate();
-
- void incomingCall(const QString& displayName);
- void endIncomingCall();
+ void incomingNotification(Notification* notification);
};
}
diff --git a/libsowatch/watch.h b/libsowatch/watch.h
index 5552a8c..eabfa06 100644
--- a/libsowatch/watch.h
+++ b/libsowatch/watch.h
@@ -21,28 +21,38 @@ public:
explicit Watch(QObject* parent = 0);
~Watch();
+ /** Return a string identiyfying this watch's model. */
virtual QString model() const = 0;
+ /** Should return true if the watch is connected. */
virtual bool isConnected() const = 0;
/** Indicates if watch is too busy atm and we should limit frame rate. */
virtual bool busy() const = 0;
+ /** Changes the current date/time on the watch. */
virtual QDateTime dateTime() = 0;
virtual void setDateTime(const QDateTime& dateTime) = 0;
+ /** Tells the watch to update the unread notifications count, if visible. */
virtual void updateNotificationCount(Notification::Type type, int count) = 0;
signals:
+ /** The watch has been found and linked to. */
void connected();
+ /** The watch connection has been lost. */
void disconnected();
+ /** The watch has returned to the idle screen by either inactivity or notification cleared/timeout. */
+ void idling();
void buttonPressed(int button);
void buttonReleased(int button);
public slots:
- virtual void vibrate(bool on) = 0;
- virtual void showNotification(const Notification& n) = 0;
- virtual void startRinging(const QString& text) = 0;
- virtual void stopRinging() = 0;
+ /** Go back to the idle screen. */
+ virtual void displayIdleScreen() = 0;
+ /** A standard notification; it's up to the watch when to stop showing it. */
+ virtual void displayNotification(Notification* n) = 0;
+ /** Enter application mode. */
+ virtual void displayApplication() = 0;
};
}
diff --git a/libsowatch/watchserver.cpp b/libsowatch/watchserver.cpp
index 942131f..d95d4fb 100644
--- a/libsowatch/watchserver.cpp
+++ b/libsowatch/watchserver.cpp
@@ -13,6 +13,7 @@ WatchServer::WatchServer(Watch* watch, QObject* parent) :
{
connect(_watch, SIGNAL(connected()), SLOT(watchConnected()));
connect(_watch, SIGNAL(disconnected()), SLOT(watchDisconnected()));
+ connect(_watch, SIGNAL(idling()), SLOT(watchIdling()));
}
Watch* WatchServer::watch()
@@ -23,13 +24,8 @@ Watch* WatchServer::watch()
void WatchServer::addProvider(NotificationProvider *provider)
{
provider->setParent(this);
-
- connect(provider, SIGNAL(notification(Notification)), SLOT(notificationEmitted(Notification)));
- connect(provider, SIGNAL(unreadCountChanged(Notification::Type)), SLOT(unreadCountUpdated(Notification::Type)));
- connect(provider, SIGNAL(incomingCall(QString)), SLOT(incomingCall(QString)));
- connect(provider, SIGNAL(endIncomingCall()), SLOT(endIncomingCall()));
-
- _providers.append(provider);
+ connect(provider, SIGNAL(incomingNotification(Notification*)), SLOT(notificationReceived(Notification*)));
+ // And that's it, really.
}
void WatchServer::runWatchlet(const QString& id)
@@ -39,7 +35,7 @@ void WatchServer::runWatchlet(const QString& id)
}
_currentWatchlet = _watchlets[id];
if (_watch->isConnected()) {
- _currentWatchlet->activate();
+ reactivateCurrentWatchlet();
}
}
@@ -58,10 +54,41 @@ void WatchServer::registerWatchlet(Watchlet *watchlet)
_watchlets[watchlet->id()] = watchlet;
}
+void WatchServer::reactivateCurrentWatchlet()
+{
+ Q_ASSERT(_currentWatchlet != 0);
+ _watch->displayApplication();
+ _currentWatchlet->activate();
+}
+
+void WatchServer::nextNotification()
+{
+ if (!_watch->isConnected()) return;
+ if (!_pendingNotifications.empty()) {
+ Notification *n = _pendingNotifications.head();
+ _watch->displayNotification(n);
+ } else if (_currentWatchlet) {
+ reactivateCurrentWatchlet();
+ } else {
+ _watch->displayIdleScreen();
+ }
+}
+
+uint WatchServer::getNotificationCount(Notification::Type type)
+{
+ uint count = 0;
+ foreach (Notification* n, _notifications[type]) {
+ count += n->count();
+ }
+ return count;
+}
+
void WatchServer::watchConnected()
{
- if (_currentWatchlet) {
- _currentWatchlet->activate();
+ if (!_pendingNotifications.isEmpty()) {
+ nextNotification();
+ } else if (_currentWatchlet) {
+ reactivateCurrentWatchlet();
}
}
@@ -70,30 +97,73 @@ void WatchServer::watchDisconnected()
if (_currentWatchlet) {
_currentWatchlet->deactivate();
}
+ _pendingNotifications.clear();
}
-void WatchServer::notificationEmitted(const Notification &notification)
+void WatchServer::watchIdling()
{
- // TODO app loses button focus...
- _watch->showNotification(notification);
+ qDebug() << "Watch idling";
+ if (!_pendingNotifications.empty()) {
+ _pendingNotifications.dequeue();
+ nextNotification();
+ }
}
-void WatchServer::unreadCountUpdated(Notification::Type type)
+void WatchServer::notificationReceived(Notification *notification)
{
- uint count = 0;
- foreach(NotificationProvider* provider, _providers)
- {
- count += provider->getCount(type);
+ const Notification::Type type = notification->type();
+ _notifications[type].append(notification);
+
+ connect(notification, SIGNAL(changed()), SLOT(notificationChanged()));
+ connect(notification, SIGNAL(cleared()), SLOT(notificationCleared()));
+
+ qDebug() << "notification received" << notification->title() << notification->count();
+
+ _watch->updateNotificationCount(type, getNotificationCount(type));
+ if (_pendingNotifications.isEmpty()) {
+ _pendingNotifications.enqueue(notification);
+ nextNotification();
+ } else if (type == Notification::CallNotification) {
+ // Oops, priority!!!!
+ _pendingNotifications.prepend(notification);
+ nextNotification();
+ } else {
+ _pendingNotifications.enqueue(notification);
}
- _watch->updateNotificationCount(type, count);
}
-void WatchServer::incomingCall(const QString &displayText)
+void WatchServer::notificationChanged()
{
- qDebug() << "Incoming call" << displayText;
+ QObject *obj = sender();
+ if (obj) {
+ Notification* n = static_cast<Notification*>(obj);
+ const Notification::Type type = n->type();
+
+ qDebug() << "notification changed" << n->title() << n->count();
+
+ _watch->updateNotificationCount(type, getNotificationCount(type));
+ if (!_pendingNotifications.isEmpty() && _pendingNotifications.head() == n) {
+ nextNotification();
+ }
+ }
}
-void WatchServer::endIncomingCall()
+void WatchServer::notificationCleared()
{
- qDebug() << "End incoming call";
+ QObject *obj = sender();
+ if (obj) {
+ Notification* n = static_cast<Notification*>(obj);
+ const Notification::Type type = n->type();
+ _notifications[type].removeOne(n);
+
+ qDebug() << "notification deleted" << n->title() << n->count();
+
+ _watch->updateNotificationCount(type, getNotificationCount(type));
+ if (!_pendingNotifications.isEmpty() && _pendingNotifications.head() == n) {
+ _pendingNotifications.removeAll(n);
+ nextNotification();
+ } else {
+ _pendingNotifications.removeAll(n);
+ }
+ }
}
diff --git a/libsowatch/watchserver.h b/libsowatch/watchserver.h
index 27d29aa..1ece104 100644
--- a/libsowatch/watchserver.h
+++ b/libsowatch/watchserver.h
@@ -1,9 +1,9 @@
#ifndef SOWATCH_WATCHSERVER_H
#define SOWATCH_WATCHSERVER_H
-#include <QtCore/QObject>
+#include <QtCore/QList>
#include <QtCore/QMap>
-#include <QtCore/QSignalMapper>
+#include <QtCore/QQueue>
#include "sowatch_global.h"
#include "notification.h"
@@ -32,20 +32,28 @@ public:
protected:
Watch* _watch;
- Watchlet* _currentWatchlet;
QMap<QString, Watchlet*> _watchlets;
- QList<NotificationProvider*> _providers;
+
+ /** Stores current notifications, classified by type. */
+ QList<Notification*> _notifications[Notification::TypeCount];
+ QQueue<Notification*> _pendingNotifications;
+
+ Watchlet* _currentWatchlet;
void registerWatchlet(Watchlet *watchlet);
+ void reactivateCurrentWatchlet();
+
+ void nextNotification();
+ uint getNotificationCount(Notification::Type type);
protected slots:
void watchConnected();
void watchDisconnected();
- void notificationEmitted(const Notification& notification);
- void unreadCountUpdated(Notification::Type type);
- void incomingCall(const QString& displayText);
- void endIncomingCall();
+ void watchIdling();
+ void notificationReceived(Notification* notification);
+ void notificationChanged();
+ void notificationCleared();
friend class Watchlet;
};
diff --git a/meegohandsetnotification/meegohandsetnotification.cpp b/meegohandsetnotification/meegohandsetnotification.cpp
new file mode 100644
index 0000000..69e2bd5
--- /dev/null
+++ b/meegohandsetnotification/meegohandsetnotification.cpp
@@ -0,0 +1,61 @@
+#include "meegohandsetnotification.h"
+
+MeegoHandsetNotification::MeegoHandsetNotification(const ::Notification& n, QObject *parent) :
+ sowatch::Notification(parent), _n(n)
+{
+}
+
+sowatch::Notification::Type MeegoHandsetNotification::type() const
+{
+ QString eventType = _n.parameters().value("eventType").toString();
+ if (eventType == "email.arrived")
+ return sowatch::Notification::EmailNotification;
+ else if (eventType == "x-nokia.call.missed")
+ return sowatch::Notification::MissedCallNotification;
+ else if (eventType == "x-nokia.messaging.im")
+ return sowatch::Notification::ImNotification;
+ else if (eventType == "x-nokia.messaging.sms")
+ return sowatch::Notification::SmsNotification;
+ else if (eventType == "x-nokia.messaging.mms")
+ return sowatch::Notification::MmsNotification;
+ else
+ return sowatch::Notification::OtherNotification;
+}
+
+uint MeegoHandsetNotification::count() const
+{
+ return _n.parameters().value("count").toUInt();
+}
+
+QDateTime MeegoHandsetNotification::dateTime() const
+{
+ const uint timestamp = _n.parameters().value("timestamp").toUInt();
+ return QDateTime::fromTime_t(timestamp);
+}
+
+QString MeegoHandsetNotification::title() const
+{
+ return _n.parameters().value("summary").toString();
+}
+
+QString MeegoHandsetNotification::body() const
+{
+ return _n.parameters().value("body").toString();
+}
+
+void MeegoHandsetNotification::activate()
+{
+ // TODO Actually do something
+}
+
+void MeegoHandsetNotification::clear()
+{
+ // TODO Actually clear...
+ emit cleared();
+}
+
+void MeegoHandsetNotification::changeTo(const ::Notification &notification)
+{
+ _n = notification;
+ emit changed();
+}
diff --git a/meegohandsetnotification/meegohandsetnotification.h b/meegohandsetnotification/meegohandsetnotification.h
new file mode 100644
index 0000000..fc9d50f
--- /dev/null
+++ b/meegohandsetnotification/meegohandsetnotification.h
@@ -0,0 +1,37 @@
+#ifndef MEEGOHANDSETNOTIFICATION_H
+#define MEEGOHANDSETNOTIFICATION_H
+
+#include <sowatch.h>
+#include <notificationsystem/notification.h>
+#include <notificationsystem/notificationparameters.h>
+
+class WatchNotificationSink;
+
+class MeegoHandsetNotification : public sowatch::Notification
+{
+ Q_OBJECT
+public:
+ explicit MeegoHandsetNotification(const ::Notification& n, QObject *parent = 0);
+
+ Type type() const;
+ uint count() const;
+ QDateTime dateTime() const;
+ QString title() const;
+ QString body() const;
+ void activate();
+ void clear();
+
+signals:
+ void changed();
+ void cleared();
+
+protected:
+ void changeTo(const ::Notification& notification);
+
+protected:
+ ::Notification _n;
+
+friend class WatchNotificationSink;
+};
+
+#endif // MEEGOHANDSETNOTIFICATION_H
diff --git a/meegohandsetnotification/meegohandsetnotification.pro b/meegohandsetnotification/meegohandsetnotification.pro
index 424eb33..e553178 100644
--- a/meegohandsetnotification/meegohandsetnotification.pro
+++ b/meegohandsetnotification/meegohandsetnotification.pro
@@ -13,12 +13,14 @@ QT += dbus
SOURCES += meegohandsetplugin.cpp \
meegohandsetnotificationprovider.cpp \
watchnotificationsink.cpp \
- mnotificationmanagerinterface.cpp
+ mnotificationmanagerinterface.cpp \
+ meegohandsetnotification.cpp
HEADERS += meegohandsetplugin.h \
meegohandsetnotificationprovider.h \
watchnotificationsink.h \
- mnotificationmanagerinterface.h
+ mnotificationmanagerinterface.h \
+ meegohandsetnotification.h
CONFIG += notificationsystem
@@ -43,3 +45,5 @@ unix:!symbian {
+
+
diff --git a/meegohandsetnotification/meegohandsetnotificationprovider.cpp b/meegohandsetnotification/meegohandsetnotificationprovider.cpp
index fc84e46..0297ebb 100644
--- a/meegohandsetnotification/meegohandsetnotificationprovider.cpp
+++ b/meegohandsetnotification/meegohandsetnotificationprovider.cpp
@@ -22,10 +22,8 @@ MeegoHandsetNotificationProvider::MeegoHandsetNotificationProvider(QObject *pare
QDBusConnection::sessionBus().registerService("com.javispedro.sowatch.MeegoHandsetNotificationSink");
QDBusConnection::sessionBus().registerObject("/meegohandsetnotificationsink", _sink);
- connect(_sink, SIGNAL(incomingNotification(sowatch::Notification)),
- SLOT(sinkNotification(sowatch::Notification)));
- connect(_sink, SIGNAL(countsChanged(sowatch::Notification::Type)),
- SLOT(sinkUnreadCountChanged(sowatch::Notification::Type)));
+ connect(_sink, SIGNAL(incomingNotification(sowatch::Notification*)),
+ SLOT(newNotification(sowatch::Notification*)));
_manager->registerSink("com.javispedro.sowatch.MeegoHandsetNotificationSink", "/meegohandsetnotificationsink");
}
@@ -35,17 +33,8 @@ MeegoHandsetNotificationProvider::~MeegoHandsetNotificationProvider()
}
-int MeegoHandsetNotificationProvider::getCount(sowatch::Notification::Type type)
-{
- return _sink->getCount(type);
-}
-
-void MeegoHandsetNotificationProvider::sinkNotification(const Notification &n)
-{
- emit notification(n);
-}
-void MeegoHandsetNotificationProvider::sinkUnreadCountChanged(Notification::Type type)
+void MeegoHandsetNotificationProvider::newNotification(Notification* n)
{
- emit unreadCountChanged(type);
+ emit incomingNotification(n);
}
diff --git a/meegohandsetnotification/meegohandsetnotificationprovider.h b/meegohandsetnotification/meegohandsetnotificationprovider.h
index 3cf78d3..f98f226 100644
--- a/meegohandsetnotification/meegohandsetnotificationprovider.h
+++ b/meegohandsetnotification/meegohandsetnotificationprovider.h
@@ -16,14 +16,12 @@ public:
explicit MeegoHandsetNotificationProvider(QObject *parent = 0);
~MeegoHandsetNotificationProvider();
- int getCount(Notification::Type type);
protected:
MNotificationManagerInterface* _manager;
WatchNotificationSink* _sink;
protected slots:
- void sinkNotification(const sowatch::Notification &n);
- void sinkUnreadCountChanged(sowatch::Notification::Type type);
+ void newNotification(sowatch::Notification *n);
friend class WatchNoficationSink;
};
diff --git a/meegohandsetnotification/watchnotificationsink.cpp b/meegohandsetnotification/watchnotificationsink.cpp
index c80c4ae..cf03c30 100644
--- a/meegohandsetnotification/watchnotificationsink.cpp
+++ b/meegohandsetnotification/watchnotificationsink.cpp
@@ -2,50 +2,33 @@
#include "watchnotificationsink.h"
WatchNotificationSink::WatchNotificationSink(sowatch::MeegoHandsetNotificationProvider *parent) :
- NotificationSink(parent), _parent(parent)
+ NotificationSink(parent)
{
- for (uint i = 0; i < maxTypes; i++) {
- _counts[i] = 0;
- }
+
}
void WatchNotificationSink::addNotification(const Notification &notification)
{
- const NotificationParameters& p = notification.parameters();
- sowatch::Notification::Type type = notificationTypeFromEventType(p.value("eventType").toString());
- const uint count = p.value("count").toUInt();
const uint notificationId = notification.notificationId();
if (_trackedNotifications.contains(notificationId)) {
- const NotificationParameters& oldParams = _trackedNotifications[notificationId].parameters();
- _counts[type] -= oldParams.value("count").toUInt();
- }
-
- _counts[type] += count;
- _trackedNotifications[notificationId] = notification;
-
- emit countsChanged(type);
-
- QDateTime dt = QDateTime::fromTime_t(p.value("timestamp").toUInt());
- QDateTime tenSecondsAgo = QDateTime::currentDateTimeUtc().addSecs(-10);
- if (dt >= tenSecondsAgo) {
- // If the notification happened recently, show it.
- sowatch::Notification n(type, dt, p.value("summary").toString(), p.value("body").toString());
- emit incomingNotification(n);
+ MeegoHandsetNotification* n = _trackedNotifications[notificationId];
+ n->changeTo(notification);
+ } else {
+ MeegoHandsetNotification* n = new MeegoHandsetNotification(notification, this);
+ _trackedNotifications[notificationId] = n;
+ emit incomingNotification(static_cast<sowatch::Notification*>(n));
}
}
void WatchNotificationSink::removeNotification(uint notificationId)
{
- Notification notification = _trackedNotifications[notificationId];
- const NotificationParameters& p = notification.parameters();
- sowatch::Notification::Type type = notificationTypeFromEventType(p.value("eventType").toString());
- uint count = p.value("count").toUInt();
-
- _counts[type] -= count;
- _trackedNotifications.remove(notificationId);
-
- emit countsChanged(type);
+ if (_trackedNotifications.contains(notificationId)) {
+ MeegoHandsetNotification* n = _trackedNotifications[notificationId];
+ _trackedNotifications.remove(notificationId);
+ n->clear();
+ n->deleteLater();
+ }
}
void WatchNotificationSink::addGroup(uint groupId, const NotificationParameters &parameters)
@@ -59,25 +42,3 @@ void WatchNotificationSink::removeGroup(uint groupId)
{
Q_UNUSED(groupId);
}
-
-int WatchNotificationSink::getCount(sowatch::Notification::Type type)
-{
- return _counts[type];
-}
-
-sowatch::Notification::Type WatchNotificationSink::notificationTypeFromEventType(const QString& eventType)
-{
- qDebug() << "incoming " << eventType;
- if (eventType == "email.arrived")
- return sowatch::Notification::EmailNotification;
- else if (eventType == "x-nokia.call.missed")
- return sowatch::Notification::MissedCallNotification;
- else if (eventType == "x-nokia.messaging.im")
- return sowatch::Notification::ImNotification;
- else if (eventType == "x-nokia.messaging.sms")
- return sowatch::Notification::SmsNotification;
- else if (eventType == "x-nokia.messaging.mms")
- return sowatch::Notification::MmsNotification;
- else
- return sowatch::Notification::OtherNotification;
-}
diff --git a/meegohandsetnotification/watchnotificationsink.h b/meegohandsetnotification/watchnotificationsink.h
index dc586a2..9500994 100644
--- a/meegohandsetnotification/watchnotificationsink.h
+++ b/meegohandsetnotification/watchnotificationsink.h
@@ -3,9 +3,8 @@
#include <QtCore/QMap>
#include <sowatch.h>
-#include <notificationsystem/notification.h>
+#include "meegohandsetnotification.h"
#include <notificationsystem/notificationsink.h>
-#include <notificationsystem/notificationparameters.h>
namespace sowatch {
class MeegoHandsetNotificationProvider;
@@ -23,19 +22,11 @@ public:
void addGroup(uint groupId, const NotificationParameters &parameters);
void removeGroup(uint groupId);
- int getCount(sowatch::Notification::Type type);
-
signals:
- void incomingNotification(const sowatch::Notification& notification);
- void countsChanged(sowatch::Notification::Type type);
+ void incomingNotification(sowatch::Notification* notification);
protected:
- static const uint maxTypes = sowatch::Notification::TypeCount;
- static sowatch::Notification::Type notificationTypeFromEventType(const QString& eventType);
-
- sowatch::MeegoHandsetNotificationProvider* _parent;
- QMap<uint, Notification> _trackedNotifications;
- uint _counts[maxTypes];
+ QMap<uint, MeegoHandsetNotification*> _trackedNotifications;
};
#endif // WATCHNOTIFICATIONSINK_H
diff --git a/metawatch/metawatch.cpp b/metawatch/metawatch.cpp
index 657548a..5e6a8fb 100644
--- a/metawatch/metawatch.cpp
+++ b/metawatch/metawatch.cpp
@@ -79,7 +79,7 @@ MetaWatch::MetaWatch(const QBluetoothAddress& address, QObject *parent) :
_paintEngine(0),
_address(address),
_socket(0),
- _24hMode(true), _dayMonthOrder(true),
+ _24hMode(true), _dayMonthOrder(true), _notificationTimeout(10),
_connectRetries(0),
_connected(false),
_connectTimer(new QTimer(this)),
@@ -87,7 +87,8 @@ MetaWatch::MetaWatch(const QBluetoothAddress& address, QObject *parent) :
_sendTimer(new QTimer(this)),
_currentMode(IdleMode),
_paintMode(IdleMode),
- _nMails(0), _nCalls(0), _nIms(0), _nSms(0), _nMms(0)
+ _nMails(0), _nCalls(0), _nIms(0), _nSms(0), _nMms(0),
+ _idleTimer(new QTimer(this)), _ringTimer(new QTimer(this))
{
QImage baseImage(screenWidth, screenHeight, QImage::Format_MonoLSB);
baseImage.setColor(0, QColor(Qt::white).rgb());
@@ -101,9 +102,16 @@ MetaWatch::MetaWatch(const QBluetoothAddress& address, QObject *parent) :
connect(_connectTimer, SIGNAL(timeout()), SLOT(retryConnect()));
connect(_connectAlignedTimer, SIGNAL(timeout()), SLOT(retryConnect()));
- _sendTimer->setInterval(30);
+ _sendTimer->setInterval(10);
connect(_sendTimer, SIGNAL(timeout()), SLOT(timedSend()));
+ _idleTimer->setInterval(_notificationTimeout * 1000);
+ _idleTimer->setSingleShot(true);
+ connect(_idleTimer, SIGNAL(timeout()), SIGNAL(idling()));
+
+ _ringTimer->setInterval(2000);
+ connect(_ringTimer, SIGNAL(timeout()), SLOT(timedRing()));
+
retryConnect();
}
@@ -217,24 +225,92 @@ void MetaWatch::updateNotificationCount(Notification::Type type, int count)
renderIdleCounts();
}
-void MetaWatch::vibrate(bool on)
+void MetaWatch::displayIdleScreen()
{
- Q_UNUSED(on); // TODO
-}
+ _currentMode = IdleMode;
+ _ringTimer->stop();
+ _idleTimer->stop();
+ setVibrateMode(false, 0, 0, 0);
+ updateDisplay(IdleMode);
+ // Usually, idle screen is kept updated, so we can show it already.
+ qDebug() << "displayIdle";
-void MetaWatch::showNotification(const Notification &n)
-{
- qDebug() << "It's time for a notification" << n.title();
}
-void MetaWatch::startRinging(const QString &text)
+void MetaWatch::displayNotification(Notification *n)
{
+ _currentMode = NotificationMode;
+ _paintMode = NotificationMode;
+ const bool shouldRing = n->type() == Notification::CallNotification;
+ configureWatchMode(NotificationMode, shouldRing ? 60 : 10);
+ QPainter p;
+ QFont lf("MetaWatch Large 16pt", 14);
+ QFont mf("MetaWatch Large 16pt", 10);
+ QImage icon = iconForNotification(n);
+ const int x = 4;
+ const int iconY = 4;
+ const int titleY = 8 + icon.height();
+ int textFlags;
+ QString text;
+
+ qDebug() << "displayNotification" << n->title() << n->body();
+
+ p.begin(this);
+
+ p.fillRect(0, 0, screenWidth, screenHeight, Qt::white);
+ p.drawImage(x, iconY, icon);
+
+ p.setPen(Qt::black);
+ p.setFont(lf);
+ textFlags = Qt::AlignLeft | Qt::AlignTop | Qt::TextWrapAnywhere;
+ text = n->title();
+
+ QRect titleMaxRect(x, titleY, screenWidth - x*2, screenHeight - titleY);
+ QRect titleRect = p.boundingRect(titleMaxRect, textFlags, text);
+ if (titleRect.width() > titleMaxRect.width()) {
+ textFlags = Qt::AlignLeft | Qt::AlignTop | Qt::TextWrapAnywhere;
+ titleRect = p.boundingRect(titleMaxRect, textFlags, text);
+ }
+
+ qDebug() << titleMaxRect << titleRect;
+ p.drawText(titleMaxRect, textFlags, text);
+
+ p.setFont(mf);
+ textFlags = Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap;
+ text = n->body();
+
+ int bodyY = titleRect.y() + titleRect.height();
+ if (bodyY >= screenHeight) return;
+ QRect bodyMaxRect(x, bodyY, titleMaxRect.width(), screenHeight - bodyY);
+ QRect bodyRect = p.boundingRect(bodyMaxRect, textFlags, text);
+ if (bodyRect.width() > bodyMaxRect.width()) {
+ textFlags = Qt::AlignLeft | Qt::AlignTop | Qt::TextWrapAnywhere;
+ }
+ qDebug() << bodyMaxRect << bodyRect;
+ p.drawText(bodyMaxRect, textFlags, text);
+
+ p.end();
+
+ if (n->type() == Notification::CallNotification) {
+ timedRing();
+ _ringTimer->start();
+ _idleTimer->stop();
+ } else {
+ _ringTimer->stop();
+ setVibrateMode(true, 500, 500, 2);
+ _idleTimer->start();
+ }
}
-void MetaWatch::stopRinging()
+void MetaWatch::displayApplication()
{
-
+ _currentMode = ApplicationMode;
+ _paintMode = ApplicationMode;
+ _ringTimer->stop();
+ _idleTimer->stop();
+ configureWatchMode(ApplicationMode, 250);
+ qDebug() << "displayApplication";
}
MetaWatch::Mode MetaWatch::currentMode() const
@@ -307,11 +383,11 @@ void MetaWatch::renderIdleScreen()
void MetaWatch::renderIdleWeather()
{
_paintMode = IdleMode;
- QFont smallFont("MetaWatch Small caps 8pt", 6);
+ QFont f("MetaWatch Small caps 8pt", 6);
QImage rain(QString(":/metawatch/graphics/weather_rain.bmp"));
QPainter p(this);
- p.setFont(smallFont);
+ p.setFont(f);
p.drawText(30, systemAreaHeight + 14, "No data!");
p.drawImage(screenWidth - 26, systemAreaHeight + 6, rain);
@@ -341,6 +417,41 @@ void MetaWatch::renderIdleCounts()
p.drawText(QRect((32 * 0) + 4, y, w, h), s.sprintf("%d", calls), opt);
p.drawText(QRect((32 * 1) + 4, y, w, h), s.sprintf("%d", sms), opt);
p.drawText(QRect((32 * 2) + 4, y, w, h), s.sprintf("%d", mails), opt);
+
+ _paintMode = _currentMode;
+}
+
+void MetaWatch::renderNotificationScreen()
+{
+ _paintMode = NotificationMode;
+ QPainter p(this);
+
+ p.fillRect(0, 0, screenWidth, screenHeight, Qt::white);
+
+ _paintMode = _currentMode;
+}
+
+QImage MetaWatch::iconForNotification(const Notification *n)
+{
+ switch (n->type()) {
+ case Notification::CallNotification:
+ case Notification::MissedCallNotification:
+ return QImage(QString(":/metawatch/graphics/phone.bmp"));
+ break;
+ case Notification::SmsNotification:
+ case Notification::MmsNotification:
+ case Notification::ImNotification:
+ return QImage(QString(":/metawatch/graphics/message.bmp"));
+ break;
+ case Notification::EmailNotification:
+ return QImage(QString(":/metawatch/graphics/email.bmp"));
+ break;
+ case Notification::CalendarNotification:
+ return QImage(QString(":/metawatch/graphics/timer.bmp"));
+ break;
+ default:
+ return QImage();
+ }
}
quint16 MetaWatch::calcCrc(const QByteArray &data, int size)
@@ -394,6 +505,20 @@ void MetaWatch::handleMessage(const Message &msg)
}
}
+void MetaWatch::setVibrateMode(bool enable, uint on, uint off, uint cycles)
+{
+ Message msg(SetVibrateMode, QByteArray(6, 0));
+
+ msg.data[0] = enable ? 1 : 0;
+ msg.data[1] = on & 0xFF;
+ msg.data[2] = on >> 8;
+ msg.data[3] = off & 0xFF;
+ msg.data[4] = off >> 8;
+ msg.data[5] = cycles;
+
+ send(msg);
+}
+
void MetaWatch::updateLine(Mode mode, const QImage& image, int line)
{
Message msg(WriteBuffer, QByteArray(13, 0), (1 << 4) | (mode & 0xF));
@@ -479,7 +604,7 @@ void MetaWatch::loadTemplate(Mode mode, int templ)
void MetaWatch::handleStatusChange(const Message &msg)
{
- qDebug() << "watch status changed" << msg.data.size();
+ qDebug() << "watch status changed" << msg.options << msg.data.at(0);
}
void MetaWatch::handleButtonEvent(const Message &msg)
@@ -487,6 +612,8 @@ void MetaWatch::handleButtonEvent(const Message &msg)
if (msg.data.size() < 1) return;
quint8 button = msg.data[0];
+ qDebug() << "button event" << msg.data.size() << msg.options << msg.data.at(0);
+
emit buttonPressed(button); // TODO This is completely broken
}
@@ -505,10 +632,9 @@ void MetaWatch::socketConnected()
setDateTime(QDateTime::currentDateTime());
configureIdleSystemArea(false);
- configureWatchMode(ApplicationMode, 240);
- configureWatchMode(NotificationMode, 30);
renderIdleScreen();
+ renderNotificationScreen();
emit connected();
}
@@ -624,6 +750,11 @@ void MetaWatch::timedSend()
}
}
+void MetaWatch::timedRing()
+{
+ setVibrateMode(true, 200, 200, 3);
+}
+
void MetaWatch::realSend(const Message &msg)
{
const int msgSize = msg.data.size();
diff --git a/metawatch/metawatch.h b/metawatch/metawatch.h
index 48b7be6..da0f323 100644
--- a/metawatch/metawatch.h
+++ b/metawatch/metawatch.h
@@ -78,10 +78,10 @@ public:
void updateNotificationCount(Notification::Type type, int count);
- void vibrate(bool on);
- void showNotification(const Notification& n);
- void startRinging(const QString &text);
- void stopRinging();
+ void displayIdleScreen();
+ void displayNotification(Notification *n);
+ void displayApplication();
+
Mode currentMode() const;
Mode paintTargetMode() const;
@@ -92,6 +92,9 @@ public:
void renderIdleScreen();
void renderIdleWeather();
void renderIdleCounts();
+ void renderNotificationScreen();
+
+ QImage iconForNotification(const Notification *n);
protected:
mutable MetaWatchPaintEngine* _paintEngine;
@@ -100,9 +103,12 @@ protected:
QBluetoothAddress _address;
QBluetoothSocket* _socket;
+ /* Some configurable stuff. */
bool _24hMode : 1;
bool _dayMonthOrder : 1;
+ short _notificationTimeout;
+
static const int connectRetryTimesSize = 6;
static const int connectRetryTimes[connectRetryTimesSize];
short _connectRetries;
@@ -130,6 +136,10 @@ protected:
// Notifications: Unread count
uint _nMails, _nCalls, _nIms, _nSms, _nMms;
+ // Notifications: timers
+ QTimer* _idleTimer;
+ QTimer* _ringTimer;
+
static const quint8 bitRevTable[16];
static const quint16 crcTable[256];
quint16 calcCrc(const QByteArray& data, int size);
@@ -138,6 +148,7 @@ protected:
void send(const Message& msg);
void handleMessage(const Message& msg);
+ void setVibrateMode(bool enable, uint on, uint off, uint cycles);
void updateLine(Mode mode, const QImage& image, int line);
void updateLines(Mode mode, const QImage& image, int lineA, int lineB);
void updateLines(Mode mode, const QImage& image, const QVector<bool>& lines);
@@ -157,6 +168,7 @@ protected slots:
void socketState(QBluetoothSocket::SocketState error);
void retryConnect();
void timedSend();
+ void timedRing();
private:
void realSend(const Message& msg);
diff --git a/metawatch/uires.qrc b/metawatch/uires.qrc
index 24d70fb..821a3dc 100644
--- a/metawatch/uires.qrc
+++ b/metawatch/uires.qrc
@@ -9,6 +9,11 @@
<file>weather_sunny.bmp</file>
<file>weather_thunderstorm.bmp</file>
<file>weather_wind.bmp</file>
+ <file>email.bmp</file>
+ <file>message.bmp</file>
+ <file>phone.bmp</file>
+ <file>play.bmp</file>
+ <file>timer.bmp</file>
</qresource>
<qresource prefix="/metawatch/fonts">
<file>metawatch_8pt_5pxl_CAPS.ttf</file>