summaryrefslogtreecommitdiff
path: root/app/pebbledinterface.cpp
diff options
context:
space:
mode:
authorTomasz Sterna <tomek@xiaoka.com>2015-01-03 16:38:02 +0100
committerTomasz Sterna <tomek@xiaoka.com>2015-01-03 19:07:48 +0100
commit4e7da1944f5fa75a0739c0757d40a8102f045365 (patch)
tree5f3fe179256536e4135eb4d5031a1d754af5e26c /app/pebbledinterface.cpp
parent4150005566bec7827ce1cdd759a2397d47eba583 (diff)
parente6ec758b364fcaf9fda35e56740c3fcd7e8fe25e (diff)
Merge remote-tracking branch 'javispedro/js-testing'
Conflicts: daemon/daemon.pro daemon/dbusconnector.cpp daemon/manager.cpp daemon/watchcommands.cpp daemon/watchcommands.h daemon/watchconnector.cpp daemon/watchconnector.h log4qt-debug.conf log4qt-release.conf rpm/pebble.spec rpm/pebble.yaml
Diffstat (limited to 'app/pebbledinterface.cpp')
-rw-r--r--app/pebbledinterface.cpp269
1 files changed, 213 insertions, 56 deletions
diff --git a/app/pebbledinterface.cpp b/app/pebbledinterface.cpp
index 05ca614..c978dd0 100644
--- a/app/pebbledinterface.cpp
+++ b/app/pebbledinterface.cpp
@@ -1,33 +1,42 @@
#include "pebbledinterface.h"
+#include "watch_interface.h"
-QString PebbledInterface::PEBBLED_SYSTEMD_UNIT("pebbled.service");
-QString PebbledInterface::PEBBLED_DBUS_SERVICE("org.pebbled");
-QString PebbledInterface::PEBBLED_DBUS_PATH("/");
-QString PebbledInterface::PEBBLED_DBUS_IFACE("org.pebbled");
-
-#define PebbledDbusInterface QDBusInterface(PEBBLED_DBUS_SERVICE, PEBBLED_DBUS_PATH, PEBBLED_DBUS_IFACE)
-
+static const QString PEBBLED_SYSTEMD_UNIT("pebbled.service");
+static const QString PEBBLED_DBUS_SERVICE("org.pebbled");
+static const QString PEBBLED_DBUS_PATH("/org/pebbled/Watch");
+static const QString PEBBLED_DBUS_IFACE("org.pebbled.Watch");
PebbledInterface::PebbledInterface(QObject *parent) :
- QObject(parent), systemd(0)
+ QObject(parent),
+ systemd(new QDBusInterface("org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ QDBusConnection::sessionBus(), this)),
+ watch(new OrgPebbledWatchInterface(PEBBLED_DBUS_SERVICE,
+ PEBBLED_DBUS_PATH,
+ QDBusConnection::sessionBus(), this))
{
- QDBusConnection::sessionBus().connect(
- PEBBLED_DBUS_SERVICE, PEBBLED_DBUS_PATH, PEBBLED_DBUS_IFACE,
- "connectedChanged", this, SIGNAL(connectedChanged()));
+ connect(watch, &OrgPebbledWatchInterface::NameChanged,
+ this, &PebbledInterface::nameChanged);
+ connect(watch, &OrgPebbledWatchInterface::AddressChanged,
+ this, &PebbledInterface::addressChanged);
+ connect(watch, &OrgPebbledWatchInterface::ConnectedChanged,
+ this, &PebbledInterface::connectedChanged);
+ connect(watch, &OrgPebbledWatchInterface::AppUuidChanged,
+ this, &PebbledInterface::appUuidChanged);
+ connect(watch, &OrgPebbledWatchInterface::AppSlotsChanged,
+ this, &PebbledInterface::refreshAppSlots);
+ connect(watch, &OrgPebbledWatchInterface::AllAppsChanged,
+ this, &PebbledInterface::refreshAllApps);
- QDBusConnection::sessionBus().connect(
- PEBBLED_DBUS_SERVICE, PEBBLED_DBUS_PATH, PEBBLED_DBUS_IFACE,
- "pebbleChanged", this, SLOT(onPebbleChanged()));
+ connect(watch, &OrgPebbledWatchInterface::ConnectedChanged,
+ this, &PebbledInterface::onWatchConnectedChanged);
// simulate connected change on active changed
// as the daemon might not had a chance to send 'connectedChanged'
// when going down
- connect(this, SIGNAL(activeChanged()), SIGNAL(connectedChanged()));
-
- systemd = new QDBusInterface("org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- QDBusConnection::sessionBus(), this);
+ connect(this, &PebbledInterface::activeChanged,
+ this, &PebbledInterface::connectedChanged);
systemd->call("Subscribe");
@@ -44,6 +53,11 @@ PebbledInterface::PebbledInterface(QObject *parent) :
} else {
qWarning() << unit.error().message();
}
+
+ if (watch->isValid()) {
+ refreshAllApps();
+ refreshAppSlots();
+ }
}
void PebbledInterface::getUnitProperties()
@@ -55,9 +69,9 @@ void PebbledInterface::getUnitProperties()
QDBusReply<QVariantMap> reply = QDBusConnection::sessionBus().call(request);
if (reply.isValid()) {
QVariantMap newProperties = reply.value();
- bool emitEnabledChanged = (properties["UnitFileState"] != newProperties["UnitFileState"]);
- bool emitActiveChanged = (properties["ActiveState"] != newProperties["ActiveState"]);
- properties = newProperties;
+ bool emitEnabledChanged = (unitProperties["UnitFileState"] != newProperties["UnitFileState"]);
+ bool emitActiveChanged = (unitProperties["ActiveState"] != newProperties["ActiveState"]);
+ unitProperties = newProperties;
if (emitEnabledChanged) emit enabledChanged();
if (emitActiveChanged) emit activeChanged();
} else {
@@ -67,24 +81,16 @@ void PebbledInterface::getUnitProperties()
void PebbledInterface::onPropertiesChanged(QString interface, QMap<QString,QVariant> changed, QStringList invalidated)
{
- qDebug() << __FUNCTION__ << interface << changed << invalidated;
+ qDebug() << Q_FUNC_INFO << interface << changed << invalidated;
if (interface != "org.freedesktop.systemd1.Unit") return;
- if (invalidated.contains("UnitFileState") or invalidated.contains("ActiveState"))
+ if (invalidated.contains("UnitFileState") || invalidated.contains("ActiveState"))
getUnitProperties();
}
-void PebbledInterface::onPebbleChanged()
-{
- qDebug() << __FUNCTION__;
- emit nameChanged();
- emit addressChanged();
- emit pebbleChanged();
-}
-
bool PebbledInterface::enabled() const
{
- qDebug() << __FUNCTION__;
- return properties["UnitFileState"].toString() == "enabled";
+ qDebug() << Q_FUNC_INFO;
+ return unitProperties["UnitFileState"].toString() == "enabled";
}
void PebbledInterface::setEnabled(bool enabled)
@@ -103,8 +109,8 @@ void PebbledInterface::setEnabled(bool enabled)
bool PebbledInterface::active() const
{
- qDebug() << __FUNCTION__;
- return properties["ActiveState"].toString() == "active";
+ qDebug() << Q_FUNC_INFO;
+ return unitProperties["ActiveState"].toString() == "active";
}
void PebbledInterface::setActive(bool active)
@@ -118,48 +124,199 @@ void PebbledInterface::setActive(bool active)
bool PebbledInterface::connected() const
{
- qDebug() << __FUNCTION__;
- return PebbledDbusInterface.property(__FUNCTION__).toBool();
+ qDebug() << Q_FUNC_INFO;
+ return watch->connected();
}
-QVariantMap PebbledInterface::pebble() const
+QString PebbledInterface::name() const
{
- qDebug() << __FUNCTION__;
- return PebbledDbusInterface.property(__FUNCTION__).toMap();
+ qDebug() << Q_FUNC_INFO;
+ return watch->name();
}
-QString PebbledInterface::name() const
+QString PebbledInterface::address() const
{
- qDebug() << __FUNCTION__;
- return PebbledDbusInterface.property(__FUNCTION__).toString();
+ qDebug() << Q_FUNC_INFO;
+ return watch->address();
}
-QString PebbledInterface::address() const
+QString PebbledInterface::appUuid() const
{
- qDebug() << __FUNCTION__;
- return PebbledDbusInterface.property(__FUNCTION__).toString();
+ qDebug() << Q_FUNC_INFO;
+ return watch->appUuid();
}
void PebbledInterface::ping()
{
- qDebug() << __FUNCTION__;
- PebbledDbusInterface.call("ping", 66);
+ qDebug() << Q_FUNC_INFO;
+ watch->Ping(66);
}
void PebbledInterface::time()
{
- qDebug() << __FUNCTION__;
- PebbledDbusInterface.call("time");
+ qDebug() << Q_FUNC_INFO;
+ watch->SyncTime();
}
void PebbledInterface::disconnect()
{
- qDebug() << __FUNCTION__;
- PebbledDbusInterface.call("disconnect");
+ qDebug() << Q_FUNC_INFO;
+ watch->Disconnect();
}
void PebbledInterface::reconnect()
{
- qDebug() << __FUNCTION__;
- PebbledDbusInterface.call("reconnect");
+ qDebug() << Q_FUNC_INFO;
+ watch->Reconnect();
+}
+
+QUrl PebbledInterface::configureApp(const QString &uuid)
+{
+ qDebug() << Q_FUNC_INFO << uuid;
+ QDBusPendingReply<QString> reply = watch->StartAppConfiguration(uuid);
+ reply.waitForFinished();
+ if (reply.isError()) {
+ qWarning() << "Received error:" << reply.error().message();
+ return QUrl();
+ } else {
+ return QUrl(reply.value());
+ }
+}
+
+bool PebbledInterface::isAppInstalled(const QString &uuid) const
+{
+ QUuid u(uuid);
+
+ foreach (const QString &s, _appSlots) {
+ if (QUuid(s) == u) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+QImage PebbledInterface::menuIconForApp(const QUuid &uuid) const
+{
+ return _appMenuIcons.value(uuid);
+}
+
+void PebbledInterface::setAppConfiguration(const QString &uuid, const QString &data)
+{
+ qDebug() << Q_FUNC_INFO << uuid << data;
+ watch->SendAppConfigurationData(uuid, data);
+}
+
+void PebbledInterface::launchApp(const QString &uuid)
+{
+ qDebug() << Q_FUNC_INFO << uuid;
+ QDBusPendingReply<> reply = watch->LaunchApp(uuid);
+ reply.waitForFinished();
+
+ // TODO Terrible hack; need to give time for the watch to open the app
+ // A better solution would be to wait until AppUuidChanged is generated.
+ QUuid u(uuid);
+ if (u.isNull()) return;
+ int sleep_count = 0;
+ while (QUuid(watch->appUuid()) != u && sleep_count < 5) {
+ qDebug() << "Waiting for" << u.toString() << "to launch";
+ QThread::sleep(1);
+ sleep_count++;
+ }
+}
+
+void PebbledInterface::uploadApp(const QString &uuid, int slot)
+{
+ qDebug() << Q_FUNC_INFO << uuid << slot;
+ QDBusPendingReply<> reply = watch->UploadApp(uuid, slot);
+ reply.waitForFinished();
+}
+
+void PebbledInterface::unloadApp(int slot)
+{
+ qDebug() << Q_FUNC_INFO << slot;
+ QDBusPendingReply<> reply = watch->UnloadApp(slot);
+ reply.waitForFinished();
+}
+
+QStringList PebbledInterface::appSlots() const
+{
+ return _appSlots;
+}
+
+QVariantList PebbledInterface::allApps() const
+{
+ return _apps;
+}
+
+QVariantMap PebbledInterface::appInfoByUuid(const QString &uuid) const
+{
+ int index = _appsByUuid.value(QUuid(uuid), -1);
+ if (index >= 0) {
+ return _apps[index].toMap();
+ } else {
+ return QVariantMap();
+ }
+}
+
+void PebbledInterface::onWatchConnectedChanged()
+{
+ qDebug() << Q_FUNC_INFO;
+ if (watch->connected()) {
+ refreshAllApps();
+ refreshAppSlots();
+ }
+}
+
+void PebbledInterface::refreshAppSlots()
+{
+ qDebug() << "refreshing app slots list";
+ _appSlots = watch->appSlots();
+ emit appSlotsChanged();
+}
+
+void PebbledInterface::refreshAllApps()
+{
+ _apps.clear();
+ _appsByUuid.clear();
+ _appMenuIcons.clear();
+
+ qDebug() << "refreshing all apps list";
+
+ const QVariantList l = watch->allApps();
+ foreach (const QVariant &v, l) {
+ QVariantMap orig = qdbus_cast<QVariantMap>(v.value<QDBusArgument>());
+ QUuid uuid = orig.value("uuid").toUuid();
+ if (uuid.isNull()) {
+ qWarning() << "Invalid app uuid received" << orig;
+ continue;
+ }
+
+ QVariantMap m;
+ m.insert("uuid", uuid.toString());
+ m.insert("shortName", orig.value("short-name"));
+ m.insert("longName", orig.value("long-name"));
+
+ QByteArray pngIcon = orig.value("menu-icon").toByteArray();
+ if (!pngIcon.isEmpty()) {
+ _appMenuIcons.insert(uuid, QImage::fromData(pngIcon, "PNG"));
+ }
+
+ _apps.append(QVariant::fromValue(m));
+ }
+
+ std::sort(_apps.begin(), _apps.end(), [](const QVariant &v1, const QVariant &v2) {
+ const QVariantMap &a = v1.toMap();
+ const QVariantMap &b = v2.toMap();
+ return a.value("shortName").toString() < b.value("shortName").toString();
+ });
+
+ for (int i = 0; i < _apps.size(); ++i) {
+ QUuid uuid = _apps[i].toMap().value("uuid").toUuid();
+ _appsByUuid.insert(uuid, i);
+ }
+
+ qDebug() << _appsByUuid.size() << "different app uuids known";
+
+ emit allAppsChanged();
}