Don't connect to GraphUpdated more than once.
[harmattan/cameraplus] / src / dbusservice.cpp
1 /*!
2  * This file is part of CameraPlus.
3  *
4  * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21 #include "dbusservice.h"
22 #include <QDBusInterface>
23 #include "platformsettings.h"
24 #include <QDeclarativeInfo>
25 #include <QDBusPendingCall>
26
27 // We cannot use ADBusInterface because it will try to introspect the service upon
28 // creation. This will lead to services being launched when we create the interfaces.
29 DbusService::DbusService(QObject *parent) :
30   QObject(parent), m_settings(0), m_enabled(false) {
31
32 }
33
34 DbusService::~DbusService() {
35
36 }
37
38 PlatformSettings *DbusService::settings() const {
39   return m_settings;
40 }
41
42 void DbusService::setSettings(PlatformSettings *settings) {
43   if (m_settings != settings) {
44     m_settings = settings;
45
46     init();
47
48     emit settingsChanged();
49   }
50 }
51
52 void DbusService::setName(const QString& name) {
53   if (m_name != name) {
54     m_name = name;
55
56     init();
57
58     emit nameChanged();
59   }
60 }
61
62 bool DbusService::isEnabled() const {
63   return m_enabled;
64 }
65
66 void DbusService::init() {
67   if (m_name.isEmpty() || !m_settings) {
68     return;
69   }
70
71   PlatformSettings::Service service = m_settings->service(m_name);
72
73   if (service.m_type != "dbus") {
74     qmlInfo(this) << "Unknown service type" << service.m_type;
75     return;
76   }
77
78   if (!service.m_enabled) {
79     qmlInfo(this) << "Not initializing a disabled service";
80     return;
81   }
82
83   m_path = service.m_path;
84   m_interface = service.m_interface;
85   m_dest = service.m_dest;
86
87   QStringList methods = service.m_method.split('|');
88   foreach (const QString& method, methods) {
89     QStringList parts = method.split(':');
90     if (parts.size() != 2) {
91       qmlInfo(this) << "Cannot parse dbus method description" << method;
92       continue;
93     }
94
95     QString id = parts[0].trimmed();
96     QString val = parts[1].trimmed();
97     if (id.isEmpty() || val.isEmpty()) {
98       qmlInfo(this) << "Empty id or value";
99       continue;
100     }
101
102     m_methods[id] = val;
103   }
104
105   m_enabled = service.m_enabled;
106   emit isEnabledChanged();
107 }
108
109 bool DbusService::asyncCall(const QString& method, const QVariant& arg) {
110   if (!m_settings) {
111     qmlInfo(this) << "Empty settings.";
112     return false;
113   }
114
115   if (!m_enabled) {
116     qmlInfo(this) << "Service is not enabled.";
117     return false;
118   }
119
120   if (m_dest.isEmpty() || m_path.isEmpty() || m_interface.isEmpty()) {
121     qmlInfo(this) << "Unable to construct DBus method call.";
122     return false;
123   }
124
125   if (method.isEmpty()) {
126     qmlInfo(this) << "Empty method call";
127     return false;
128   }
129
130   if (!m_methods.contains(method)) {
131     qmlInfo(this) << "Unknown method call ID" << method;
132     return false;
133   }
134
135   QString call = m_methods[method];
136
137   QDBusMessage msg = QDBusMessage::createMethodCall(m_dest, m_path, m_interface, call);
138   msg.setAutoStartService(true);
139   if (arg.isValid()) {
140     msg.setArguments(QList<QVariant>() << arg);
141   }
142
143   QDBusConnection conn = QDBusConnection::sessionBus();
144   if (!conn.isConnected()) {
145     qmlInfo(this) << "Unable to connect to DBus session bus.";
146     return false;
147   }
148
149   conn.asyncCall(msg);
150
151   return true;
152 }