register the cloud service as a plugin in the devicemanager

implementing the notifications interface
This commit is contained in:
Michael Zanetti 2017-10-06 22:19:37 +02:00
parent 05da66421d
commit c1d4adea17
10 changed files with 422 additions and 68 deletions

View File

@ -159,6 +159,7 @@ void AWSConnector::setupSubscriptions()
subscriptions.append(QString("%1/device/name/response").arg(m_clientId));
subscriptions.append(QString("%1/device/users/response").arg(m_clientId));
subscriptions.append(QString("%1/pair/response").arg(m_clientId));
subscriptions.append(QString("%1/notify/response").arg(m_clientId));
subscribe(subscriptions);
// fetch previous pairings
@ -174,17 +175,36 @@ void AWSConnector::fetchPairings()
publish(QString("%1/device/users").arg(m_clientId), params);
}
void AWSConnector::onPairingsRetrieved(const QVariantList &pairings)
void AWSConnector::onPairingsRetrieved(const QVariantMap &pairings)
{
qCDebug(dcAWS) << pairings.count() << "devices paired in cloud.";
if (pairings.count() > 0) {
qCDebug(dcAWS) << pairings.value("users").toList().count() << "devices paired in cloud.";
if (pairings.value("users").toList().count() > 0) {
QStringList topics;
foreach (const QVariant &pairing, pairings) {
foreach (const QVariant &pairing, pairings.value("users").toList()) {
topics << QString("%1/%2/#").arg(m_clientId).arg(pairing.toString());
}
subscribe(topics);
}
qCDebug(dcAWS) << pairings.value("pushNotificationsEndpoints").toList().count() << "push notification enabled users paired in cloud.";
QList<PushNotificationsEndpoint> pushNotificationEndpoints;
if (pairings.value("pushNotificationsEndpoints").toList().count() > 0) {
foreach (const QVariant &pairing, pairings.value("pushNotificationsEndpoints").toList()) {
foreach (const QString &cognitoUserId, pairing.toMap().keys()) {
qCDebug(dcAWS()) << "User:" << cognitoUserId << "has" << pairing.toMap().value(cognitoUserId).toList().count() << "push notifications enabled devices.";
foreach (const QVariant &endpoint, pairing.toMap().value(cognitoUserId).toList()) {
PushNotificationsEndpoint ep;
ep.userId = cognitoUserId;
ep.endpointId = endpoint.toMap().value("endpointId").toString();
ep.displayName = endpoint.toMap().value("displayName").toString();
pushNotificationEndpoints.append(ep);
qCDebug(dcAWS) << "Device:" << ep.displayName << "endpoint:" << ep.endpointId << "user:" << ep.userId;
}
}
}
}
emit pushNotificationEndpointsUpdated(pushNotificationEndpoints);
if (readSyncedNameCache() != m_clientName) {
setName();
}
@ -237,6 +257,18 @@ void AWSConnector::sendWebRtcHandshakeMessage(const QString &sessionId, const QV
publish(sessionId + "/reply", map);
}
int AWSConnector::sendPushNotification(const QString &userId, const QString &endpointId, const QString &title, const QString &text)
{
QVariantMap params;
params.insert("id", ++m_transactionId);
params.insert("command", "sendPushNotification");
params.insert("title", title);
params.insert("body", text);
params.insert("timestamp", QDateTime::currentMSecsSinceEpoch());
publish(QString("%1/notify/user/%2/%3").arg(m_clientId, userId, endpointId), params);
return m_transactionId;
}
quint16 AWSConnector::publish(const QString &topic, const QVariantMap &message)
{
if (!m_setupInProgress && !isConnected()) {
@ -418,7 +450,7 @@ ResponseCode AWSConnector::onSubscriptionReceivedCallback(util::String topic_nam
qCWarning(dcAWS()) << "Received a pairing response for a transaction we didn't start";
}
} else if (topic == QString("%1/device/users/response").arg(connector->m_clientId)) {
connector->staticMetaObject.invokeMethod(connector, "onPairingsRetrieved", Qt::QueuedConnection, Q_ARG(QVariantList, jsonDoc.toVariant().toMap().value("users").toList()));
connector->staticMetaObject.invokeMethod(connector, "onPairingsRetrieved", Qt::QueuedConnection, Q_ARG(QVariantMap, jsonDoc.toVariant().toMap()));
} else if (topic == QString("%1/device/name/response").arg(connector->m_clientId)) {
qCDebug(dcAWS) << "Set device name in cloud with status:" << jsonDoc.toVariant().toMap().value("status").toInt();
if (jsonDoc.toVariant().toMap().value("status").toInt() == 200) {
@ -438,6 +470,11 @@ ResponseCode AWSConnector::onSubscriptionReceivedCallback(util::String topic_nam
connector->webRtcHandshakeMessageReceived(topic, jsonDoc.toVariant().toMap());
} else if (topic.startsWith(QString("%1/eu-west-1:").arg(connector->m_clientId)) && topic.contains("reply")) {
// silently drop our own things (should not be subscribed to that in the first place)
} else if (topic == QString("%1/notify/response").arg(connector->m_clientId)) {
int transactionId = jsonDoc.toVariant().toMap().value("id").toInt();
int status = jsonDoc.toVariant().toMap().value("status").toInt();
qCDebug(dcAWS()) << "Push notification reply for transaction" << transactionId << " Status:" << status << jsonDoc.toVariant().toMap().value("message").toString();
emit connector->pushNotificationSent(transactionId, status);
} else {
qCWarning(dcAWS) << "Unhandled subscription received!" << topic << QString::fromStdString(payload);
}

View File

@ -39,6 +39,13 @@ public:
explicit AWSConnector(QObject *parent = 0);
~AWSConnector();
class PushNotificationsEndpoint {
public:
QString userId;
QString endpointId;
QString displayName;
};
void connect2AWS(const QString &endpoint, const QString &clientId, const QString &clientName, const QString &caFile, const QString &clientCertFile, const QString &clientPrivKeyFile);
void disconnectAWS();
bool isConnected() const;
@ -48,11 +55,16 @@ public:
void sendWebRtcHandshakeMessage(const QString &sessionId, const QVariantMap &map);
public slots:
int sendPushNotification(const QString &userId, const QString &endpointId, const QString &title, const QString &text);
signals:
void connected();
void disconnected();
void devicePaired(const QString &cognritoUserId, int errorCode, const QString &message);
void webRtcHandshakeMessageReceived(const QString &transactionId, const QVariantMap &data);
void pushNotificationEndpointsUpdated(const QList<PushNotificationsEndpoint> pushNotificationEndpoints);
void pushNotificationSent(int id, int status);
private slots:
void doConnect();
@ -61,7 +73,7 @@ private slots:
void onDeviceRegistered(bool needsReconnect);
void setupSubscriptions();
void fetchPairings();
void onPairingsRetrieved(const QVariantList &pairings);
void onPairingsRetrieved(const QVariantMap &pairings);
void setName();
void onDisconnected();

View File

@ -22,6 +22,8 @@
#include "awsconnector.h"
#include "janusconnector.h"
#include "loggingcategories.h"
#include "cloudnotifications.h"
CloudManager::CloudManager(NetworkManager *networkManager, QObject *parent) : QObject(parent),
m_networkManager(networkManager)
@ -130,6 +132,12 @@ bool CloudManager::keepAlive(const QString &sessionId)
return m_janusConnector->sendKeepAliveMessage(sessionId);
}
CloudNotifications *CloudManager::createNotificationsPlugin() const
{
CloudNotifications* notifications = new CloudNotifications(m_awsConnector);
return notifications;
}
void CloudManager::connect2aws()
{
m_awsConnector->connect2AWS(m_serverUrl,

View File

@ -30,6 +30,7 @@
class JanusConnector;
class AWSConnector;
class CloudNotifications;
class CloudManager : public QObject
{
@ -51,6 +52,8 @@ public:
bool keepAlive(const QString &sessionId);
CloudNotifications* createNotificationsPlugin() const;
signals:
void connectedChanged(bool connected);
@ -80,6 +83,8 @@ private:
QString m_caCertificate;
QString m_clientCertificate;
QString m_clientCertificateKey;
CloudNotifications *m_notifications;
};
#endif // CLOUDMANAGER_H

View File

@ -0,0 +1,209 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2017 Michael Zanetti <michael.zanetti@guh.io> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "cloudnotifications.h"
#include "loggingcategories.h"
#include <QDebug>
DeviceClassId cloudNotificationsDeviceClassId = DeviceClassId("81c1bbcc-543a-48fd-bd18-ab6a76f9c38d");
ParamTypeId cloudNotificationsDeviceClassUserParamId = ParamTypeId("5bdeaf08-91a9-42bc-a9f9-ef6b02ecaa3c");
ParamTypeId cloudNotificationsDeviceClassEndpointParamId = ParamTypeId("e7c41785-dd3b-4f46-b5b4-1f8a7d060ddd");
ActionTypeId notifyActionTypeId = ActionTypeId("211d1f25-28e7-4eba-8938-b29de0e41571");
ParamTypeId notifyActionParamTitleId = ParamTypeId("096503fc-b343-4d7f-8387-96162faf0f8e");
ParamTypeId notifyActionParamBodyId = ParamTypeId("4bd0fa87-c663-4621-8040-99b6d535387c");
StateTypeId connectedStateTypeId = StateTypeId("518e27b6-c3bf-49d7-be24-05ae978c00f7");
CloudNotifications::CloudNotifications(AWSConnector* awsConnector, QObject *parent):
DevicePlugin(parent),
m_awsConnector(awsConnector)
{
connect(m_awsConnector, &AWSConnector::pushNotificationEndpointsUpdated, this, &CloudNotifications::pushNotificationEndpointsUpdated);
connect(m_awsConnector, &AWSConnector::pushNotificationSent, this, &CloudNotifications::pushNotificationSent);
}
QJsonObject CloudNotifications::metaData() const
{
QVariantMap pluginMetaData;
pluginMetaData.insert("id", "ccc6dbc8-e352-48a1-8e87-3c89a4669fc2");
pluginMetaData.insert("name", "cloudNotifications");
pluginMetaData.insert("displayName", "Cloud Notifications");
QVariantList interfaces;
interfaces.append("notifications");
interfaces.append("connectable");
QVariantList createMethods;
createMethods.append("auto");
QVariantMap userIdParam;
userIdParam.insert("id", cloudNotificationsDeviceClassUserParamId);
userIdParam.insert("name", "userId");
userIdParam.insert("displayName", "User ID");
userIdParam.insert("type", "QString");
QVariantMap endpointIdParam;
endpointIdParam.insert("id", cloudNotificationsDeviceClassEndpointParamId);
endpointIdParam.insert("name", "endpoint");
endpointIdParam.insert("displayName", "Device");
endpointIdParam.insert("type", "QString");
QVariantList cloudNotificationDeviceClassParamTypes;
cloudNotificationDeviceClassParamTypes.append(userIdParam);
cloudNotificationDeviceClassParamTypes.append(endpointIdParam);
QVariantMap notifyActionParamTitle;
notifyActionParamTitle.insert("id", notifyActionParamTitleId);
notifyActionParamTitle.insert("name", "title");
notifyActionParamTitle.insert("displayName", "Title");
notifyActionParamTitle.insert("type", "QString");
QVariantMap notifyActionParamBody;
notifyActionParamBody.insert("id", notifyActionParamBodyId);
notifyActionParamBody.insert("name", "body");
notifyActionParamBody.insert("displayName", "Message text");
notifyActionParamBody.insert("type", "QString");
QVariantList notifyActionParamTypes;
notifyActionParamTypes.append(notifyActionParamTitle);
notifyActionParamTypes.append(notifyActionParamBody);
QVariantMap notifyAction;
notifyAction.insert("id", notifyActionTypeId);
notifyAction.insert("name", "notify");
notifyAction.insert("displayName", "Send notification");
notifyAction.insert("paramTypes", notifyActionParamTypes);
QVariantList actionTypes;
actionTypes.append(notifyAction);
QVariantMap connectedState;
connectedState.insert("id", connectedStateTypeId);
connectedState.insert("name", "connected");
connectedState.insert("displayName", "connected");
connectedState.insert("type", "bool");
connectedState.insert("displayNameEvent", "Connected changed");
connectedState.insert("defaultValue", false);
QVariantList stateTypes;
stateTypes.append(connectedState);
QVariantMap cloudNotificationsDeviceClass;
cloudNotificationsDeviceClass.insert("id", cloudNotificationsDeviceClassId);
cloudNotificationsDeviceClass.insert("name", "cloudNotifications");
cloudNotificationsDeviceClass.insert("displayName", "Cloud Notifications");
cloudNotificationsDeviceClass.insert("createMethods", createMethods);
cloudNotificationsDeviceClass.insert("paramTypes", cloudNotificationDeviceClassParamTypes);
cloudNotificationsDeviceClass.insert("interfaces", interfaces);
cloudNotificationsDeviceClass.insert("actionTypes", actionTypes);
cloudNotificationsDeviceClass.insert("stateTypes", stateTypes);
QVariantList deviceClasses;
deviceClasses.append(cloudNotificationsDeviceClass);
QVariantMap guhVendor;
guhVendor.insert("id", "2062d64d-3232-433c-88bc-0d33c0ba2ba6"); // guh's id
guhVendor.insert("name", "guh");
guhVendor.insert("displayName", "guh");
guhVendor.insert("deviceClasses", deviceClasses);
QVariantList vendors;
vendors.append(guhVendor);
pluginMetaData.insert("vendors", vendors);
return QJsonObject::fromVariantMap(pluginMetaData);
}
DeviceManager::DeviceSetupStatus CloudNotifications::setupDevice(Device *device)
{
qWarning() << "--------------------------------------------------------------------- setupDevice" << device->id() << device->name();
Q_UNUSED(device)
return DeviceManager::DeviceSetupStatusSuccess;
}
void CloudNotifications::startMonitoringAutoDevices()
{
}
DeviceManager::DeviceError CloudNotifications::executeAction(Device *device, const Action &action)
{
qCDebug(dcCloud()) << "executeAction" << device << action.id() << action.params();
QString userId = device->paramValue(cloudNotificationsDeviceClassUserParamId).toString();
QString endpointId = device->paramValue(cloudNotificationsDeviceClassEndpointParamId).toString();
int id = m_awsConnector->sendPushNotification(userId, endpointId, action.param(notifyActionParamTitleId).value().toString(), action.param(notifyActionParamBodyId).value().toString());
m_pendingPushNotifications.insert(id, action.id());
return DeviceManager::DeviceErrorAsync;
}
void CloudNotifications::pushNotificationEndpointsUpdated(const QList<AWSConnector::PushNotificationsEndpoint> &endpoints)
{
qCDebug(dcCloud()) << "Push Notification endpoint update";
QList<Device*> devicesToRemove;
foreach (Device *configuredDevice, myDevices()) {
bool found = false;
foreach (const AWSConnector::PushNotificationsEndpoint &ep, endpoints) {
if (configuredDevice->paramValue(cloudNotificationsDeviceClassUserParamId).toString() == ep.userId
&& configuredDevice->paramValue(cloudNotificationsDeviceClassEndpointParamId).toString() == ep.endpointId) {
found = true;
break;
}
}
if (!found) {
devicesToRemove.append(configuredDevice);
}
}
foreach (Device *d, devicesToRemove) {
emit autoDeviceDisappeared(d->id());
}
QList<DeviceDescriptor> devicesToAdd;
foreach (const AWSConnector::PushNotificationsEndpoint &ep, endpoints) {
bool found = false;
foreach (Device *d, myDevices()) {
if (d->paramValue(cloudNotificationsDeviceClassUserParamId).toString() == ep.userId
&& d->paramValue(cloudNotificationsDeviceClassEndpointParamId).toString() == ep.endpointId) {
found = true;
break;
}
}
if (!found) {
qCDebug(dcCloud) << "Adding new notification device" << ep.displayName;
DeviceDescriptor descriptor(cloudNotificationsDeviceClassId, ep.displayName, QString("Send notifications to %1").arg(ep.displayName));
ParamList params;
Param userIdParam(cloudNotificationsDeviceClassUserParamId, ep.userId);
params.append(userIdParam);
Param endpointIdParam(cloudNotificationsDeviceClassEndpointParamId, ep.endpointId);
params.append(endpointIdParam);
descriptor.setParams(params);
devicesToAdd.append(descriptor);
}
}
emit autoDevicesAppeared(cloudNotificationsDeviceClassId, devicesToAdd);
}
void CloudNotifications::pushNotificationSent(int id, int status)
{
qCDebug(dcCloud()) << "Push notification sent" << id << status;
ActionId actionId = m_pendingPushNotifications.value(id);
emit actionExecutionFinished(actionId, status == 200 ? DeviceManager::DeviceErrorNoError : DeviceManager::DeviceErrorHardwareNotAvailable);
}

View File

@ -0,0 +1,52 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2017 Michael Zanetti <michael.zanetti@guh.io> *
* *
* This file is part of guh. *
* *
* Guh is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, version 2 of the License. *
* *
* Guh is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef CLOUDNOTIFICATIONS_H
#define CLOUDNOTIFICATIONS_H
#include "plugin/deviceplugin.h"
#include "awsconnector.h"
class CloudNotifications : public DevicePlugin
{
Q_OBJECT
// Q_PLUGIN_METADATA(IID "guru.guh.DevicePlugin" FILE "deviceplugincloudnotifications.json")
Q_INTERFACES(DevicePlugin)
public:
CloudNotifications(AWSConnector *awsConnector, QObject* parent = nullptr);
QJsonObject metaData() const;
DeviceManager::DeviceSetupStatus setupDevice(Device *device) override;
void startMonitoringAutoDevices() override;
DeviceManager::DeviceError executeAction(Device *device, const Action &action) override;
private slots:
void pushNotificationEndpointsUpdated(const QList<AWSConnector::PushNotificationsEndpoint> &endpoints);
void pushNotificationSent(int id, int status);
private:
AWSConnector *m_awsConnector = nullptr;
QHash<int, ActionId> m_pendingPushNotifications;
};
#endif // CLOUDNOTIFICATIONS_H

View File

@ -103,6 +103,7 @@
#include "devicemanager.h"
#include "plugin/device.h"
#include "cloudnotifications.h"
namespace guhserver {
@ -506,6 +507,9 @@ void GuhCore::init() {
m_cloudManager->setClientCertificates(m_configuration->cloudCertificateCA(), m_configuration->cloudCertificate(), m_configuration->cloudCertificateKey());
m_cloudManager->setEnabled(m_configuration->cloudEnabled());
CloudNotifications *cloudNotifications = m_cloudManager->createNotificationsPlugin();
m_deviceManager->registerStaticPlugin(cloudNotifications, cloudNotifications->metaData());
connect(m_configuration, &GuhConfiguration::localeChanged, this, &GuhCore::onLocaleChanged);
connect(m_configuration, &GuhConfiguration::cloudEnabledChanged, m_cloudManager, &CloudManager::setEnabled);
connect(m_configuration, &GuhConfiguration::serverNameChanged, m_cloudManager, &CloudManager::setDeviceName);

View File

@ -73,6 +73,7 @@ HEADERS += guhcore.h \
certificategenerator.h \
awsconnector.h \
cloudmanager.h \
cloudnotifications.h \
MbedTLS/MbedTLSConnection.hpp \
janusconnector.h \
pushbuttondbusservice.h \
@ -96,7 +97,6 @@ HEADERS += guhcore.h \
hardware/network/avahi/qtavahiservicebrowserimplementation.h \
hardware/network/avahi/qtavahiservicebrowserimplementation_p.h \
SOURCES += guhcore.cpp \
tcpserver.cpp \
mocktcpserver.cpp \
@ -151,6 +151,7 @@ SOURCES += guhcore.cpp \
certificategenerator.cpp \
awsconnector.cpp \
cloudmanager.cpp \
cloudnotifications.cpp \
MbedTLS/MbedTLSConnection.cpp \
janusconnector.cpp \
pushbuttondbusservice.cpp \

View File

@ -208,7 +208,12 @@ DeviceManager::~DeviceManager()
}
foreach (DevicePlugin *plugin, m_devicePlugins) {
delete plugin;
if (plugin->parent() == this) {
qCDebug(dcDeviceManager()) << "Deleting plugin" << plugin->pluginName();
delete plugin;
} else {
qCDebug(dcDeviceManager()) << "Not deleting plugin" << plugin->pluginName();
}
}
}
@ -254,6 +259,19 @@ QList<QJsonObject> DeviceManager::pluginsMetadata()
return pluginList;
}
/*! Register a DevicePlugin class. This can be used to create devices internally from the guh system without having to create a full plugin.
The DeviceManager takes ownership of the object and will clean it up when exiting. Do not delete the object yourself. */
void DeviceManager::registerStaticPlugin(DevicePlugin *plugin, const QJsonObject &metaData)
{
if (!verifyPluginMetadata(metaData)) {
qCWarning(dcDeviceManager()) << "Failed to verify plugin metadata. Not loading static plugin:" << plugin->pluginName();
return;
}
plugin->setParent(this);
plugin->setMetaData(metaData);
loadPlugin(plugin);
}
/*! Set the \a locale of all plugins and reload the translated strings. */
void DeviceManager::setLocale(const QLocale &locale)
{
@ -1014,75 +1032,81 @@ void DeviceManager::loadPlugins()
qCWarning(dcDeviceManager) << "Could not get plugin instance of" << entry;
continue;
}
pluginIface->setParent(this);
if (!verifyPluginMetadata(loader.metaData().value("MetaData").toObject()))
continue;
pluginIface->setMetaData(loader.metaData().value("MetaData").toObject());
pluginIface->setLocale(m_locale);
qApp->installTranslator(pluginIface->translator());
pluginIface->initPlugin(this);
qCDebug(dcDeviceManager) << "**** Loaded plugin" << pluginIface->pluginName();
foreach (const Vendor &vendor, pluginIface->supportedVendors()) {
qCDebug(dcDeviceManager) << "* Loaded vendor:" << vendor.name();
if (m_supportedVendors.contains(vendor.id()))
continue;
m_supportedVendors.insert(vendor.id(), vendor);
}
foreach (const DeviceClass &deviceClass, pluginIface->supportedDevices()) {
if (!m_supportedVendors.contains(deviceClass.vendorId())) {
qCWarning(dcDeviceManager) << "Vendor not found. Ignoring device. VendorId:" << deviceClass.vendorId() << "DeviceClass:" << deviceClass.name() << deviceClass.id();
continue;
}
m_vendorDeviceMap[deviceClass.vendorId()].append(deviceClass.id());
m_supportedDevices.insert(deviceClass.id(), deviceClass);
qCDebug(dcDeviceManager) << "* Loaded device class:" << deviceClass.name();
}
GuhSettings settings(GuhSettings::SettingsRolePlugins);
settings.beginGroup("PluginConfig");
ParamList params;
if (settings.childGroups().contains(pluginIface->pluginId().toString())) {
settings.beginGroup(pluginIface->pluginId().toString());
foreach (const QString &paramTypeIdString, settings.allKeys()) {
Param param(ParamTypeId(paramTypeIdString), settings.value(paramTypeIdString));
params.append(param);
}
settings.endGroup();
} else if (!pluginIface->configurationDescription().isEmpty()){
// plugin requires config but none stored. Init with defaults
foreach (const ParamType &paramType, pluginIface->configurationDescription()) {
Param param(paramType.id(), paramType.defaultValue());
params.append(param);
}
}
settings.endGroup();
if (params.count() > 0) {
DeviceError status = pluginIface->setConfiguration(params);
if (status != DeviceErrorNoError) {
qCWarning(dcDeviceManager) << "Error setting params to plugin. Broken configuration?";
}
}
m_devicePlugins.insert(pluginIface->pluginId(), pluginIface);
connect(pluginIface, &DevicePlugin::emitEvent, this, &DeviceManager::eventTriggered);
connect(pluginIface, &DevicePlugin::devicesDiscovered, this, &DeviceManager::slotDevicesDiscovered, Qt::QueuedConnection);
connect(pluginIface, &DevicePlugin::deviceSetupFinished, this, &DeviceManager::slotDeviceSetupFinished);
connect(pluginIface, &DevicePlugin::actionExecutionFinished, this, &DeviceManager::actionExecutionFinished);
connect(pluginIface, &DevicePlugin::pairingFinished, this, &DeviceManager::slotPairingFinished);
connect(pluginIface, &DevicePlugin::autoDevicesAppeared, this, &DeviceManager::onAutoDevicesAppeared);
connect(pluginIface, &DevicePlugin::autoDeviceDisappeared, this, &DeviceManager::onAutoDeviceDisappeared);
loadPlugin(pluginIface);
}
}
}
void DeviceManager::loadPlugin(DevicePlugin *pluginIface)
{
pluginIface->setLocale(m_locale);
qApp->installTranslator(pluginIface->translator());
pluginIface->initPlugin(this);
qCDebug(dcDeviceManager) << "**** Loaded plugin" << pluginIface->pluginName();
foreach (const Vendor &vendor, pluginIface->supportedVendors()) {
qCDebug(dcDeviceManager) << "* Loaded vendor:" << vendor.name();
if (m_supportedVendors.contains(vendor.id()))
continue;
m_supportedVendors.insert(vendor.id(), vendor);
}
foreach (const DeviceClass &deviceClass, pluginIface->supportedDevices()) {
if (!m_supportedVendors.contains(deviceClass.vendorId())) {
qCWarning(dcDeviceManager) << "Vendor not found. Ignoring device. VendorId:" << deviceClass.vendorId() << "DeviceClass:" << deviceClass.name() << deviceClass.id();
continue;
}
m_vendorDeviceMap[deviceClass.vendorId()].append(deviceClass.id());
m_supportedDevices.insert(deviceClass.id(), deviceClass);
qCDebug(dcDeviceManager) << "* Loaded device class:" << deviceClass.name();
}
GuhSettings settings(GuhSettings::SettingsRolePlugins);
settings.beginGroup("PluginConfig");
ParamList params;
if (settings.childGroups().contains(pluginIface->pluginId().toString())) {
settings.beginGroup(pluginIface->pluginId().toString());
foreach (const QString &paramTypeIdString, settings.allKeys()) {
Param param(ParamTypeId(paramTypeIdString), settings.value(paramTypeIdString));
params.append(param);
}
settings.endGroup();
} else if (!pluginIface->configurationDescription().isEmpty()){
// plugin requires config but none stored. Init with defaults
foreach (const ParamType &paramType, pluginIface->configurationDescription()) {
Param param(paramType.id(), paramType.defaultValue());
params.append(param);
}
}
settings.endGroup();
if (params.count() > 0) {
DeviceError status = pluginIface->setConfiguration(params);
if (status != DeviceErrorNoError) {
qCWarning(dcDeviceManager) << "Error setting params to plugin. Broken configuration?";
}
}
m_devicePlugins.insert(pluginIface->pluginId(), pluginIface);
connect(pluginIface, &DevicePlugin::emitEvent, this, &DeviceManager::eventTriggered);
connect(pluginIface, &DevicePlugin::devicesDiscovered, this, &DeviceManager::slotDevicesDiscovered, Qt::QueuedConnection);
connect(pluginIface, &DevicePlugin::deviceSetupFinished, this, &DeviceManager::slotDeviceSetupFinished);
connect(pluginIface, &DevicePlugin::actionExecutionFinished, this, &DeviceManager::actionExecutionFinished);
connect(pluginIface, &DevicePlugin::pairingFinished, this, &DeviceManager::slotPairingFinished);
connect(pluginIface, &DevicePlugin::autoDevicesAppeared, this, &DeviceManager::onAutoDevicesAppeared);
connect(pluginIface, &DevicePlugin::autoDeviceDisappeared, this, &DeviceManager::onAutoDeviceDisappeared);
}
void DeviceManager::loadConfiguredDevices()
{
GuhSettings settings(GuhSettings::SettingsRoleDevices);
@ -1324,7 +1348,7 @@ void DeviceManager::onAutoDevicesAppeared(const DeviceClassId &deviceClassId, co
foreach (const DeviceDescriptor &deviceDescriptor, deviceDescriptors) {
Device *device = new Device(plugin->pluginId(), deviceClassId, this);
device->m_autoCreated = true;
device->setName(deviceClass.name());
device->setName(deviceDescriptor.title());
device->setParams(deviceDescriptor.params());
DeviceSetupStatus setupStatus = setupDevice(device);

View File

@ -95,6 +95,7 @@ public:
static QStringList pluginSearchDirs();
static QList<QJsonObject> pluginsMetadata();
void registerStaticPlugin(DevicePlugin* plugin, const QJsonObject &metaData);
void setLocale(const QLocale &locale);
@ -158,6 +159,7 @@ public slots:
private slots:
void loadPlugins();
void loadPlugin(DevicePlugin *pluginIface);
void loadConfiguredDevices();
void storeConfiguredDevices();
void startMonitoringAutoDevices();