summaryrefslogtreecommitdiff
path: root/daemon/appmanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/appmanager.cpp')
-rw-r--r--daemon/appmanager.cpp184
1 files changed, 2 insertions, 182 deletions
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);
}