summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Sterna <tomek@xiaoka.com>2015-01-07 00:37:15 +0100
committerTomasz Sterna <tomek@xiaoka.com>2015-01-07 00:37:15 +0100
commit16ddb4d6ca5742aa36112f187e36a039a7357460 (patch)
treefc8b0acdf1883f5d34863a8c063b2d642d1fe100
parenta55f8f218ea9b52e97b9b7de1ac43502ce8c9994 (diff)
Refactored whole app handling into AppInfo class
-rw-r--r--daemon/appinfo.cpp309
-rw-r--r--daemon/appinfo.h74
-rw-r--r--daemon/appmanager.cpp184
-rw-r--r--daemon/appmanager.h2
-rw-r--r--daemon/bankmanager.cpp22
-rw-r--r--daemon/bankmanager.h31
-rw-r--r--daemon/jskitmanager.cpp6
-rw-r--r--daemon/manager.cpp4
8 files changed, 321 insertions, 311 deletions
diff --git a/daemon/appinfo.cpp b/daemon/appinfo.cpp
index 587ed8b..91467b0 100644
--- a/daemon/appinfo.cpp
+++ b/daemon/appinfo.cpp
@@ -1,9 +1,23 @@
#include <QSharedData>
#include <QBuffer>
+#include <QDir>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
#include "appinfo.h"
+#include "unpacker.h"
+#include "stm32crc.h"
+
+namespace {
+struct ResourceEntry {
+ int index;
+ quint32 offset;
+ quint32 length;
+ quint32 crc;
+};
+}
struct AppInfoData : public QSharedData {
- bool local;
QUuid uuid;
QString shortName;
QString longName;
@@ -15,17 +29,21 @@ struct AppInfoData : public QSharedData {
AppInfo::Capabilities capabilities;
QHash<QString, int> keyInts;
QHash<int, QString> keyNames;
- QImage menuIcon;
+ bool menuIcon;
+ int menuIconResource;
QString path;
};
+QLoggingCategory AppInfo::l("AppInfo");
+
AppInfo::AppInfo() : d(new AppInfoData)
{
- d->local = false;
d->versionCode = 0;
d->watchface = false;
d->jskit = false;
d->capabilities = 0;
+ d->menuIcon = false;
+ d->menuIconResource = -1;
}
AppInfo::AppInfo(const AppInfo &rhs) : d(rhs.d)
@@ -45,22 +63,22 @@ AppInfo::~AppInfo()
bool AppInfo::isLocal() const
{
- return d->local;
+ return ! d->path.isEmpty();
}
-void AppInfo::setLocal(const bool local)
+bool AppInfo::isValid() const
{
- d->local = local;
+ return ! d->uuid.isNull();
}
-QUuid AppInfo::uuid() const
+void AppInfo::setInvalid()
{
- return d->uuid;
+ d->uuid = QUuid(); // Clear the uuid to force invalid app
}
-void AppInfo::setUuid(const QUuid &uuid)
+QUuid AppInfo::uuid() const
{
- d->uuid = uuid;
+ return d->uuid;
}
QString AppInfo::shortName() const
@@ -68,81 +86,41 @@ QString AppInfo::shortName() const
return d->shortName;
}
-void AppInfo::setShortName(const QString &string)
-{
- d->shortName = string;
-}
-
QString AppInfo::longName() const
{
return d->longName;
}
-void AppInfo::setLongName(const QString &string)
-{
- d->longName = string;
-}
-
QString AppInfo::companyName() const
{
return d->companyName;
}
-void AppInfo::setCompanyName(const QString &string)
-{
- d->companyName = string;
-}
-
int AppInfo::versionCode() const
{
return d->versionCode;
}
-void AppInfo::setVersionCode(int code)
-{
- d->versionCode = code;
-}
-
QString AppInfo::versionLabel() const
{
return d->versionLabel;
}
-void AppInfo::setVersionLabel(const QString &string)
-{
- d->versionLabel = string;
-}
-
bool AppInfo::isWatchface() const
{
return d->watchface;
}
-void AppInfo::setWatchface(bool b)
-{
- d->watchface = b;
-}
-
bool AppInfo::isJSKit() const
{
return d->jskit;
}
-void AppInfo::setJSKit(bool b)
-{
- d->jskit = b;
-}
-
AppInfo::Capabilities AppInfo::capabilities() const
{
return d->capabilities;
}
-void AppInfo::setCapabilities(Capabilities caps)
-{
- d->capabilities = caps;
-}
-
void AppInfo::addAppKey(const QString &key, int value)
{
d->keyInts.insert(key, value);
@@ -169,32 +147,243 @@ int AppInfo::valueForAppKey(const QString &key) const
return d->keyInts.value(key, -1);
}
-QImage AppInfo::menuIcon() const
+bool AppInfo::hasMenuIcon() const
+{
+ return d->menuIcon && d->menuIconResource >= 0;
+}
+
+QImage AppInfo::getMenuIconImage() const
{
- return d->menuIcon;
+ if (hasMenuIcon()) {
+ QByteArray data = extractFromResourcePack(
+ QDir(d->path).filePath("app_resources.pbpack"), d->menuIconResource);
+ if (!data.isEmpty()) {
+ return decodeResourceImage(data);
+ }
+ }
+
+ return QImage();
}
-QByteArray AppInfo::menuIconAsPng() const
+QByteArray AppInfo::getMenuIconPng() const
{
QByteArray data;
QBuffer buf(&data);
buf.open(QIODevice::WriteOnly);
- d->menuIcon.save(&buf, "PNG");
+ getMenuIconImage().save(&buf, "PNG");
buf.close();
return data;
}
-void AppInfo::setMenuIcon(const QImage &img)
+QString AppInfo::getJSApp() const
+{
+ if (!isValid() || !isLocal()) return QString();
+
+ QFile file(d->path + "/pebble-js-app.js");
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qCWarning(l) << "Failed to load JS file:" << file.fileName();
+ return QString();
+ }
+
+ return QString::fromUtf8(file.readAll());
+
+}
+
+AppInfo AppInfo::fromPath(const QString &path)
+{
+ AppInfo info;
+
+ QDir appDir(path);
+ if (!appDir.isReadable()) {
+ qCWarning(l) << "app" << appDir.absolutePath() << "is not readable";
+ return info;
+ }
+
+ QFile appInfoFile(path + "/appinfo.json");
+ if (!appInfoFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qCWarning(l) << "cannot open app info file" << appInfoFile.fileName() << ":"
+ << appInfoFile.errorString();
+ return info;
+ }
+
+ QJsonParseError parseError;
+ QJsonDocument doc = QJsonDocument::fromJson(appInfoFile.readAll(), &parseError);
+ if (parseError.error != QJsonParseError::NoError) {
+ qCWarning(l) << "cannot parse app info file" << appInfoFile.fileName() << ":"
+ << parseError.errorString();
+ return info;
+ }
+
+ const QJsonObject root = doc.object();
+ info.d->uuid = QUuid(root["uuid"].toString());
+ info.d->shortName = root["shortName"].toString();
+ info.d->longName = root["longName"].toString();
+ info.d->companyName = root["companyName"].toString();
+ info.d->versionCode = root["versionCode"].toInt();
+ info.d->versionLabel = root["versionLabel"].toString();
+
+ const QJsonObject watchapp = root["watchapp"].toObject();
+ info.d->watchface = watchapp["watchface"].toBool();
+ info.d->jskit = appDir.exists("pebble-js-app.js");
+
+ if (root.contains("capabilities")) {
+ const QJsonArray capabilities = root["capabilities"].toArray();
+ AppInfo::Capabilities caps = 0;
+ for (auto it = capabilities.constBegin(); it != capabilities.constEnd(); ++it) {
+ QString cap = (*it).toString();
+ if (cap == "location") caps |= AppInfo::Location;
+ if (cap == "configurable") caps |= AppInfo::Configurable;
+ }
+ info.d->capabilities = caps;
+ }
+
+ if (root.contains("appKeys")) {
+ const QJsonObject appkeys = root["appKeys"].toObject();
+ for (auto it = appkeys.constBegin(); it != appkeys.constEnd(); ++it) {
+ info.addAppKey(it.key(), it.value().toInt());
+ }
+ }
+
+ if (root.contains("resources")) {
+ const QJsonObject resources = root["resources"].toObject();
+ const QJsonArray media = resources["media"].toArray();
+ int index = 0;
+
+ for (auto it = media.constBegin(); it != media.constEnd(); ++it) {
+ const QJsonObject res = (*it).toObject();
+ const QJsonValue menuIcon = res["menuIcon"];
+
+ switch (menuIcon.type()) {
+ case QJsonValue::Bool:
+ info.d->menuIcon = menuIcon.toBool();
+ info.d->menuIconResource = index;
+ break;
+ case QJsonValue::String:
+ info.d->menuIcon = !menuIcon.toString().isEmpty();
+ info.d->menuIconResource = index;
+ break;
+ default:
+ break;
+ }
+
+ index++;
+ }
+ }
+
+ info.d->path = path;
+
+ if (info.uuid().isNull() || info.shortName().isEmpty()) {
+ qCWarning(l) << "invalid or empty uuid/name in" << appInfoFile.fileName();
+ return AppInfo();
+ }
+
+ return info;
+}
+
+AppInfo AppInfo::fromSlot(const BankManager::SlotInfo &slot)
{
- d->menuIcon = img;
+ AppInfo info;
+
+ info.d->uuid = QUuid::createUuid();
+ info.d->shortName = slot.name;
+ info.d->companyName = slot.company;
+ info.d->versionCode = slot.version;
+ info.d->capabilities = AppInfo::Capabilities(slot.flags);
+
+ return info;
+}
+
+QByteArray AppInfo::extractFromResourcePack(const QString &file, int wanted_id) const
+{
+ QFile f(file);
+ if (!f.open(QIODevice::ReadOnly)) {
+ qCWarning(l) << "cannot open resource file" << f.fileName();
+ return QByteArray();
+ }
+
+ QByteArray data = f.readAll();
+ Unpacker u(data);
+
+ int num_files = u.readLE<quint32>();
+ u.readLE<quint32>(); // crc for entire file
+ u.readLE<quint32>(); // timestamp
+
+ qCDebug(l) << "reading" << num_files << "resources from" << file;
+
+ QList<ResourceEntry> table;
+
+ for (int i = 0; i < num_files; i++) {
+ ResourceEntry e;
+ e.index = u.readLE<quint32>();
+ e.offset = u.readLE<quint32>();
+ e.length = u.readLE<quint32>();
+ e.crc = u.readLE<quint32>();
+
+ if (u.bad()) {
+ qCWarning(l) << "short read on resource file";
+ return QByteArray();
+ }
+
+ table.append(e);
+ }
+
+ if (wanted_id >= table.size()) {
+ qCWarning(l) << "specified resource does not exist";
+ return QByteArray();
+ }
+
+ const ResourceEntry &e = table[wanted_id];
+
+ int offset = 12 + 256 * 16 + e.offset;
+
+ QByteArray res = data.mid(offset, e.length);
+
+ Stm32Crc crc;
+ crc.addData(res);
+
+ if (crc.result() != e.crc) {
+ qCWarning(l) << "CRC failure in resource" << e.index << "on file" << file;
+ return QByteArray();
+ }
+
+ return res;
}
-QString AppInfo::path() const
+QImage AppInfo::decodeResourceImage(const QByteArray &data) const
{
- return d->path;
+ Unpacker u(data);
+ int scanline = u.readLE<quint16>();
+ u.skip(sizeof(quint16) + sizeof(quint32));
+ int width = u.readLE<quint16>();
+ int height = u.readLE<quint16>();
+
+ QImage img(width, height, QImage::Format_MonoLSB);
+ const uchar *src = reinterpret_cast<const uchar *>(&data.constData()[12]);
+ for (int line = 0; line < height; ++line) {
+ memcpy(img.scanLine(line), src, qMin(scanline, img.bytesPerLine()));
+ src += scanline;
+ }
+
+ return img;
}
-void AppInfo::setPath(const QString &string)
+// TODO: abstract to QIOReader
+QString AppInfo::filePath(enum AppInfo::File file) const
{
- d->path = string;
+ QString fileName;
+ switch (file) {
+ case AppInfo::BINARY:
+ fileName = "pebble-app.bin";
+ break;
+ case AppInfo::RESOURCES:
+ fileName = "app_resources.pbpack";
+ break;
+ }
+
+ QDir appDir(d->path);
+ if (appDir.exists(fileName)) {
+ return appDir.absoluteFilePath(fileName);
+ }
+
+ return QString();
}
diff --git a/daemon/appinfo.h b/daemon/appinfo.h
index c0b5e72..2048c38 100644
--- a/daemon/appinfo.h
+++ b/daemon/appinfo.h
@@ -5,6 +5,8 @@
#include <QUuid>
#include <QHash>
#include <QImage>
+#include <QLoggingCategory>
+#include "bankmanager.h"
class AppInfoData;
@@ -12,6 +14,8 @@ class AppInfo
{
Q_GADGET
+ static QLoggingCategory l;
+
public:
enum Capability {
Location = 1 << 0,
@@ -19,18 +23,27 @@ public:
};
Q_DECLARE_FLAGS(Capabilities, Capability)
- Q_PROPERTY(bool local READ isLocal WRITE setLocal)
- Q_PROPERTY(QUuid uuid READ uuid WRITE setUuid)
- Q_PROPERTY(QString shortName READ shortName WRITE setShortName)
- Q_PROPERTY(QString longName READ longName WRITE setLongName)
- Q_PROPERTY(QString companyName READ companyName WRITE setCompanyName)
- Q_PROPERTY(int versionCode READ versionCode WRITE setVersionCode)
- Q_PROPERTY(QString versionLabel READ versionLabel WRITE setVersionLabel)
- Q_PROPERTY(bool watchface READ isWatchface WRITE setWatchface)
- Q_PROPERTY(bool jskit READ isJSKit WRITE setJSKit)
- Q_PROPERTY(Capabilities capabilities READ capabilities WRITE setCapabilities)
- Q_PROPERTY(QImage menuIcon READ menuIcon WRITE setMenuIcon)
- Q_PROPERTY(QString path READ path WRITE setPath)
+ enum File {
+ BINARY,
+ RESOURCES
+ };
+
+ Q_PROPERTY(bool local READ isLocal)
+ Q_PROPERTY(bool valid READ isValid)
+ Q_PROPERTY(QUuid uuid READ uuid)
+ Q_PROPERTY(QString shortName READ shortName)
+ Q_PROPERTY(QString longName READ longName)
+ Q_PROPERTY(QString companyName READ companyName)
+ Q_PROPERTY(int versionCode READ versionCode)
+ Q_PROPERTY(QString versionLabel READ versionLabel)
+ Q_PROPERTY(bool watchface READ isWatchface)
+ Q_PROPERTY(bool jskit READ isJSKit)
+ Q_PROPERTY(Capabilities capabilities READ capabilities)
+ Q_PROPERTY(bool menuIcon READ hasMenuIcon)
+ Q_PROPERTY(QImage menuIconImage READ getMenuIconImage)
+
+ static AppInfo fromPath(const QString &path);
+ static AppInfo fromSlot(const BankManager::SlotInfo &slot);
public:
AppInfo();
@@ -39,49 +52,36 @@ public:
~AppInfo();
bool isLocal() const;
- void setLocal(const bool local);
-
+ bool isValid() const;
QUuid uuid() const;
- void setUuid(const QUuid &uuid);
-
QString shortName() const;
- void setShortName(const QString &string);
-
QString longName() const;
- void setLongName(const QString &string);
-
QString companyName() const;
- void setCompanyName(const QString &string);
-
int versionCode() const;
- void setVersionCode(int code);
-
QString versionLabel() const;
- void setVersionLabel(const QString &string);
-
bool isWatchface() const;
- void setWatchface(bool b);
-
bool isJSKit() const;
- void setJSKit(bool b);
-
Capabilities capabilities() const;
- void setCapabilities(Capabilities caps);
+ bool hasMenuIcon() const;
void addAppKey(const QString &key, int value);
-
bool hasAppKeyValue(int value) const;
QString appKeyForValue(int value) const;
bool hasAppKey(const QString &key) const;
int valueForAppKey(const QString &key) const;
- QImage menuIcon() const;
- QByteArray menuIconAsPng() const;
- void setMenuIcon(const QImage &img);
+ QImage getMenuIconImage() const;
+ QByteArray getMenuIconPng() const;
+ QString getJSApp() const;
+
+ QString filePath(enum File) const;
+
+ void setInvalid();
- QString path() const;
- void setPath(const QString &string);
+protected:
+ QByteArray extractFromResourcePack(const QString &file, int id) const;
+ QImage decodeResourceImage(const QByteArray &data) const;
private:
QSharedDataPointer<AppInfoData> d;
diff --git a/daemon/appmanager.cpp b/daemon/appmanager.cpp
index 24335bc..d79c761 100644
--- a/daemon/appmanager.cpp
+++ b/daemon/appmanager.cpp
@@ -1,20 +1,6 @@
#include <QStandardPaths>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonArray>
#include <QDir>
#include "appmanager.h"
-#include "unpacker.h"
-#include "stm32crc.h"
-
-namespace {
-struct ResourceEntry {
- int index;
- quint32 offset;
- quint32 length;
- quint32 crc;
-};
-}
AppManager::AppManager(QObject *parent)
: QObject(parent), l(metaObject()->className()),
@@ -101,172 +87,6 @@ void AppManager::insertAppInfo(const AppInfo &info)
void AppManager::scanApp(const QString &path)
{
qCDebug(l) << "scanning app" << path;
- QDir appDir(path);
- if (!appDir.isReadable()) {
- qCWarning(l) << "app" << appDir.absolutePath() << "is not readable";
- return;
- }
-
- QFile appInfoFile(path + "/appinfo.json");
- if (!appInfoFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qCWarning(l) << "cannot open app info file" << appInfoFile.fileName() << ":"
- << appInfoFile.errorString();
- return;
- }
-
- QJsonParseError parseError;
- QJsonDocument doc = QJsonDocument::fromJson(appInfoFile.readAll(), &parseError);
- if (parseError.error != QJsonParseError::NoError) {
- qCWarning(l) << "cannot parse app info file" << appInfoFile.fileName() << ":"
- << parseError.errorString();
- return;
- }
-
- const QJsonObject root = doc.object();
- AppInfo info;
- info.setLocal(true);
- info.setUuid(QUuid(root["uuid"].toString()));
- info.setShortName(root["shortName"].toString());
- info.setLongName(root["longName"].toString());
- info.setCompanyName(root["companyName"].toString());
- info.setVersionCode(root["versionCode"].toInt());
- info.setVersionLabel(root["versionLabel"].toString());
-
- const QJsonObject watchapp = root["watchapp"].toObject();
- info.setWatchface(watchapp["watchface"].toBool());
- info.setJSKit(appDir.exists("pebble-js-app.js"));
-
- if (root.contains("capabilities")) {
- const QJsonArray capabilities = root["capabilities"].toArray();
- AppInfo::Capabilities caps = 0;
- for (auto it = capabilities.constBegin(); it != capabilities.constEnd(); ++it) {
- QString cap = (*it).toString();
- if (cap == "location") caps |= AppInfo::Location;
- if (cap == "configurable") caps |= AppInfo::Configurable;
- }
- info.setCapabilities(caps);
- }
-
- if (root.contains("appKeys")) {
- const QJsonObject appkeys = root["appKeys"].toObject();
- for (auto it = appkeys.constBegin(); it != appkeys.constEnd(); ++it) {
- info.addAppKey(it.key(), it.value().toInt());
- }
- }
-
- if (root.contains("resources")) {
- const QJsonObject resources = root["resources"].toObject();
- const QJsonArray media = resources["media"].toArray();
- int index = 0;
-
- for (auto it = media.constBegin(); it != media.constEnd(); ++it) {
- const QJsonObject res = (*it).toObject();
- const QJsonValue menuIcon = res["menuIcon"];
-
- bool is_menu_icon = false;
- switch (menuIcon.type()) {
- case QJsonValue::Bool:
- is_menu_icon = menuIcon.toBool();
- break;
- case QJsonValue::String:
- is_menu_icon = !menuIcon.toString().isEmpty();
- break;
- default:
- break;
- }
-
- if (is_menu_icon) {
- QByteArray data = extractFromResourcePack(appDir.filePath("app_resources.pbpack"), index);
- if (!data.isEmpty()) {
- QImage icon = decodeResourceImage(data);
- info.setMenuIcon(icon);
- }
- }
-
- index++;
- }
- }
-
- info.setPath(path);
-
- if (info.uuid().isNull() || info.shortName().isEmpty()) {
- qCWarning(l) << "invalid or empty uuid/name in" << appInfoFile.fileName();
- return;
- }
-
- insertAppInfo(info);
-}
-
-QByteArray AppManager::extractFromResourcePack(const QString &file, int wanted_id) const
-{
- QFile f(file);
- if (!f.open(QIODevice::ReadOnly)) {
- qCWarning(l) << "cannot open resource file" << f.fileName();
- return QByteArray();
- }
-
- QByteArray data = f.readAll();
- Unpacker u(data);
-
- int num_files = u.readLE<quint32>();
- u.readLE<quint32>(); // crc for entire file
- u.readLE<quint32>(); // timestamp
-
- qCDebug(l) << "reading" << num_files << "resources from" << file;
-
- QList<ResourceEntry> table;
-
- for (int i = 0; i < num_files; i++) {
- ResourceEntry e;
- e.index = u.readLE<quint32>();
- e.offset = u.readLE<quint32>();
- e.length = u.readLE<quint32>();
- e.crc = u.readLE<quint32>();
-
- if (u.bad()) {
- qCWarning(l) << "short read on resource file";
- return QByteArray();
- }
-
- table.append(e);
- }
-
- if (wanted_id >= table.size()) {
- qCWarning(l) << "specified resource does not exist";
- return QByteArray();
- }
-
- const ResourceEntry &e = table[wanted_id];
-
- int offset = 12 + 256 * 16 + e.offset;
-
- QByteArray res = data.mid(offset, e.length);
-
- Stm32Crc crc;
- crc.addData(res);
-
- if (crc.result() != e.crc) {
- qCWarning(l) << "CRC failure in resource" << e.index << "on file" << file;
- return QByteArray();
- }
-
- return res;
-}
-
-QImage AppManager::decodeResourceImage(const QByteArray &data) const
-{
- Unpacker u(data);
- int scanline = u.readLE<quint16>();
- u.skip(sizeof(quint16) + sizeof(quint32));
- int width = u.readLE<quint16>();
- int height = u.readLE<quint16>();
-
- QImage img(width, height, QImage::Format_MonoLSB);
- const uchar *src = reinterpret_cast<const uchar *>(&data.constData()[12]);
- for (int line = 0; line < height; ++line) {
- memcpy(img.scanLine(line), src, qMin(scanline, img.bytesPerLine()));
- src += scanline;
- }
-
- return img;
+ const AppInfo &info = AppInfo::fromPath(path);
+ if (info.isLocal()) insertAppInfo(info);
}
diff --git a/daemon/appmanager.h b/daemon/appmanager.h
index cc98ef1..9fdb977 100644
--- a/daemon/appmanager.h
+++ b/daemon/appmanager.h
@@ -32,8 +32,6 @@ signals:
private:
void scanApp(const QString &path);
- QByteArray extractFromResourcePack(const QString &file, int id) const;
- QImage decodeResourceImage(const QByteArray &data) const;
private:
QFileSystemWatcher *_watcher;
diff --git a/daemon/bankmanager.cpp b/daemon/bankmanager.cpp
index 041f4c6..8f31959 100644
--- a/daemon/bankmanager.cpp
+++ b/daemon/bankmanager.cpp
@@ -3,6 +3,9 @@
#include "unpacker.h"
#include "packer.h"
#include "bankmanager.h"
+#include "watchconnector.h"
+#include "uploadmanager.h"
+#include "appmanager.h"
#if 0
// TODO -- This is how language files seems to be installed.
@@ -75,11 +78,9 @@ bool BankManager::uploadApp(const QUuid &uuid, int slot)
return false;
}
- QDir appDir(info.path());
+ qCDebug(l) << "about to install app " << info.shortName() << "into slot" << slot;
- qCDebug(l) << "about to install app from" << appDir.absolutePath() << "into slot" << slot;
-
- QFile *binaryFile = new QFile(appDir.absoluteFilePath("pebble-app.bin"), this);
+ QFile *binaryFile = new QFile(info.filePath(AppInfo::BINARY), this);
if (!binaryFile->open(QIODevice::ReadOnly)) {
qCWarning(l) << "failed to open" << binaryFile->fileName() << ":" << binaryFile->errorString();
delete binaryFile;
@@ -89,10 +90,12 @@ bool BankManager::uploadApp(const QUuid &uuid, int slot)
qCDebug(l) << "binary file size is" << binaryFile->size();
QFile *resourceFile = 0;
- if (appDir.exists("app_resources.pbpack")) {
- resourceFile = new QFile(appDir.absoluteFilePath("app_resources.pbpack"), this);
+ QString resourceFileName = info.filePath(AppInfo::RESOURCES);
+ if (!resourceFileName.isEmpty()) {
+ resourceFile = new QFile(resourceFileName, this);
if (!resourceFile->open(QIODevice::ReadOnly)) {
qCWarning(l) << "failed to open" << resourceFile->fileName() << ":" << resourceFile->errorString();
+ delete binaryFile;
delete resourceFile;
return false;
}
@@ -263,12 +266,7 @@ void BankManager::refresh()
AppInfo info = apps->info(name);
if (info.shortName() != name) {
- info.setLocal(false);
- info.setUuid(QUuid::createUuid());
- info.setShortName(name);
- info.setCompanyName(company);
- info.setVersionCode(version);
- info.setCapabilities(AppInfo::Capabilities(flags));
+ info = AppInfo::fromSlot(_slots[index]);
apps->insertAppInfo(info);
}
QUuid uuid = info.uuid();
diff --git a/daemon/bankmanager.h b/daemon/bankmanager.h
index 7532812..583109d 100644
--- a/daemon/bankmanager.h
+++ b/daemon/bankmanager.h
@@ -1,9 +1,14 @@
#ifndef BANKMANAGER_H
#define BANKMANAGER_H
-#include "watchconnector.h"
-#include "uploadmanager.h"
-#include "appmanager.h"
+#include <QTimer>
+#include <QUuid>
+#include <QVector>
+#include <QLoggingCategory>
+
+class WatchConnector;
+class UploadManager;
+class AppManager;
class BankManager : public QObject
{
@@ -11,6 +16,16 @@ class BankManager : public QObject
QLoggingCategory l;
public:
+ struct SlotInfo {
+ bool used;
+ quint32 id;
+ QString name;
+ QString company;
+ quint32 flags;
+ quint16 version;
+ QUuid uuid;
+ };
+
explicit BankManager(WatchConnector *watch, UploadManager *upload, AppManager *apps, QObject *parent = 0);
int numSlots() const;
@@ -46,16 +61,6 @@ private:
GeneralFailure = 4
};
- struct SlotInfo {
- bool used;
- quint32 id;
- QString name;
- QString company;
- quint32 flags;
- quint16 version;
- QUuid uuid;
- };
-
QVector<SlotInfo> _slots;
QTimer *_refresh;
};
diff --git a/daemon/jskitmanager.cpp b/daemon/jskitmanager.cpp
index f6a3f24..a5be709 100644
--- a/daemon/jskitmanager.cpp
+++ b/daemon/jskitmanager.cpp
@@ -79,7 +79,7 @@ void JSKitManager::handleAppStopped(const QUuid &uuid)
}
stopJsApp();
- _curApp.setUuid(QUuid()); // Clear the uuid to force invalid app
+ _curApp.setInvalid();
}
}
@@ -162,8 +162,8 @@ void JSKitManager::startJsApp()
// Polyfills...
loadJsFile("/usr/share/pebble/js/typedarray.js");
- // Now load the actual script
- loadJsFile(_curApp.path() + "/pebble-js-app.js");
+ // Now the actual script
+ _engine->evaluate(_curApp.getJSApp());
// Setup the message callback
QUuid uuid = _curApp.uuid();
diff --git a/daemon/manager.cpp b/daemon/manager.cpp
index 557fa07..7a3239f 100644
--- a/daemon/manager.cpp
+++ b/daemon/manager.cpp
@@ -382,8 +382,8 @@ QVariantList PebbledProxy::AllApps() const
m.insert("version-label", QVariant::fromValue(info.versionLabel()));
m.insert("is-watchface", QVariant::fromValue(info.isWatchface()));
- if (!info.menuIcon().isNull()) {
- m.insert("menu-icon", QVariant::fromValue(info.menuIconAsPng()));
+ if (!info.getMenuIconImage().isNull()) {
+ m.insert("menu-icon", QVariant::fromValue(info.getMenuIconPng()));
}
l.append(QVariant::fromValue(m));