qdbusabstractinterface.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/****************************************************************************-
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtDBus module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/****************************************************************************
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtDBus module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
9** Commercial License Usage -
10** Licensees holding valid commercial Qt licenses may use this file in -
11** accordance with the commercial license agreement provided with the -
12** Software or, alternatively, in accordance with the terms contained in -
13** a written agreement between you and Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qdbusabstractinterface.h" -
43#include "qdbusabstractinterface_p.h" -
44 -
45#include <qthread.h> -
46 -
47#include "qdbusargument.h" -
48#include "qdbuspendingcall.h" -
49#include "qdbusmessage_p.h" -
50#include "qdbusmetaobject_p.h" -
51#include "qdbusmetatype_p.h" -
52#include "qdbusutil_p.h" -
53 -
54#include <qdebug.h> -
55 -
56#ifndef QT_NO_DBUS -
57 -
58QT_BEGIN_NAMESPACE -
59 -
60static QDBusError checkIfValid(const QString &service, const QString &path, -
61 const QString &interface, bool isDynamic, bool isPeer) -
62{ -
63 // We should be throwing exceptions here... oh well -
64 QDBusError error; -
65 -
66 // dynamic interfaces (QDBusInterface) can have empty interfaces, but not service and object paths -
67 // non-dynamic is the opposite: service and object paths can be empty, but not the interface -
68 if (!isDynamic) { -
69 // use assertion here because this should never happen, at all -
70 Q_ASSERT_X(!interface.isEmpty(), "QDBusAbstractInterface", "Interface name cannot be empty"); -
71 } -
72 if (!QDBusUtil::checkBusName(service, (isDynamic && !isPeer) ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error)) -
73 return error; -
74 if (!QDBusUtil::checkObjectPath(path, isDynamic ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error)) -
75 return error; -
76 if (!QDBusUtil::checkInterfaceName(interface, QDBusUtil::EmptyAllowed, &error)) -
77 return error; -
78 -
79 // no error -
80 return QDBusError(); -
81} -
82 -
83QDBusAbstractInterfacePrivate::QDBusAbstractInterfacePrivate(const QString &serv, -
84 const QString &p, -
85 const QString &iface, -
86 const QDBusConnection& con, -
87 bool isDynamic) -
88 : connection(con), service(serv), path(p), interface(iface), -
89 lastError(checkIfValid(serv, p, iface, isDynamic, (connectionPrivate() && -
90 connectionPrivate()->mode == QDBusConnectionPrivate::PeerMode))), -
91 timeout(-1), -
92 isValid(!lastError.isValid()) -
93{ -
94 if (!isValid) -
95 return; -
96 -
97 if (!connection.isConnected()) { -
98 lastError = QDBusError(QDBusError::Disconnected, -
99 QLatin1String("Not connected to D-Bus server")); -
100 } else if (!service.isEmpty()) { -
101 currentOwner = connectionPrivate()->getNameOwner(service); // verify the name owner -
102 if (currentOwner.isEmpty()) { -
103 lastError = connectionPrivate()->lastError; -
104 } -
105 } -
106} -
107 -
108bool QDBusAbstractInterfacePrivate::canMakeCalls() const -
109{ -
110 // recheck only if we have a wildcard (i.e. empty) service or path -
111 // if any are empty, set the error message according to QDBusUtil -
112 if (service.isEmpty() && connectionPrivate()->mode != QDBusConnectionPrivate::PeerMode) -
113 return QDBusUtil::checkBusName(service, QDBusUtil::EmptyNotAllowed, &lastError); -
114 if (path.isEmpty()) -
115 return QDBusUtil::checkObjectPath(path, QDBusUtil::EmptyNotAllowed, &lastError); -
116 return true; -
117} -
118 -
119void QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, QVariant &where) const -
120{ -
121 if (!isValid || !canMakeCalls()) { // can't make calls
evaluated: !isValid
TRUEFALSE
yes
Evaluation Count:6
yes
Evaluation Count:25
evaluated: !canMakeCalls()
TRUEFALSE
yes
Evaluation Count:8
yes
Evaluation Count:17
6-25
122 where.clear();
executed (the execution status of this line is deduced): where.clear();
-
123 return;
executed: return;
Execution Count:14
14
124 } -
125 -
126 // is this metatype registered? -
127 const char *expectedSignature = "";
executed (the execution status of this line is deduced): const char *expectedSignature = "";
-
128 if (int(mp.type()) != QMetaType::QVariant) {
partially evaluated: int(mp.type()) != QMetaType::QVariant
TRUEFALSE
yes
Evaluation Count:17
no
Evaluation Count:0
0-17
129 expectedSignature = QDBusMetaType::typeToSignature(where.userType());
executed (the execution status of this line is deduced): expectedSignature = QDBusMetaType::typeToSignature(where.userType());
-
130 if (expectedSignature == 0) {
partially evaluated: expectedSignature == 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:17
0-17
131 qWarning("QDBusAbstractInterface: type %s must be registered with QtDBusQt D-Bus before it can be "
never executed (the execution status of this line is deduced): QMessageLogger("qdbusabstractinterface.cpp", 131, __PRETTY_FUNCTION__).warning("QDBusAbstractInterface: type %s must be registered with Qt D-Bus before it can be "
-
132 "used to read property %s.%s",
never executed (the execution status of this line is deduced): "used to read property %s.%s",
-
133 mp.typeName(), qPrintable(interface), mp.name());
never executed (the execution status of this line is deduced): mp.typeName(), QString(interface).toLocal8Bit().constData(), mp.name());
-
134 lastError = QDBusError(QDBusError::Failed,
never executed (the execution status of this line is deduced): lastError = QDBusError(QDBusError::Failed,
-
135 QString::fromLatin1("Unregistered type %1 cannot be handled")
never executed (the execution status of this line is deduced): QString::fromLatin1("Unregistered type %1 cannot be handled")
-
136 .arg(QLatin1String(mp.typeName())));
never executed (the execution status of this line is deduced): .arg(QLatin1String(mp.typeName())));
-
137 where.clear();
never executed (the execution status of this line is deduced): where.clear();
-
138 return;
never executed: return;
0
139 } -
140 }
executed: }
Execution Count:17
17
141 -
142 // try to read this property -
143 QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
executed (the execution status of this line is deduced): QDBusMessage msg = QDBusMessage::createMethodCall(service, path,
-
144 QLatin1String(DBUS_INTERFACE_PROPERTIES),
executed (the execution status of this line is deduced): QLatin1String("org.freedesktop.DBus.Properties"),
-
145 QLatin1String("Get"));
executed (the execution status of this line is deduced): QLatin1String("Get"));
-
146 QDBusMessagePrivate::setParametersValidated(msg, true);
executed (the execution status of this line is deduced): QDBusMessagePrivate::setParametersValidated(msg, true);
-
147 msg << interface << QString::fromUtf8(mp.name());
executed (the execution status of this line is deduced): msg << interface << QString::fromUtf8(mp.name());
-
148 QDBusMessage reply = connection.call(msg, QDBus::Block, timeout);
executed (the execution status of this line is deduced): QDBusMessage reply = connection.call(msg, QDBus::Block, timeout);
-
149 -
150 if (reply.type() != QDBusMessage::ReplyMessage) {
evaluated: reply.type() != QDBusMessage::ReplyMessage
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:16
1-16
151 lastError = QDBusError(reply);
executed (the execution status of this line is deduced): lastError = QDBusError(reply);
-
152 where.clear();
executed (the execution status of this line is deduced): where.clear();
-
153 return;
executed: return;
Execution Count:1
1
154 } -
155 if (reply.signature() != QLatin1String("v")) {
partially evaluated: reply.signature() != QLatin1String("v")
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:16
0-16
156 QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
never executed (the execution status of this line is deduced): QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
-
157 DBUS_INTERFACE_PROPERTIES);
never executed (the execution status of this line is deduced): "org.freedesktop.DBus.Properties");
-
158 lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature()));
never executed (the execution status of this line is deduced): lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature()));
-
159 where.clear();
never executed (the execution status of this line is deduced): where.clear();
-
160 return;
never executed: return;
0
161 } -
162 -
163 QByteArray foundSignature;
executed (the execution status of this line is deduced): QByteArray foundSignature;
-
164 const char *foundType = 0;
executed (the execution status of this line is deduced): const char *foundType = 0;
-
165 QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant();
executed (the execution status of this line is deduced): QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant();
-
166 -
167 if (value.userType() == where.userType() || mp.userType() == QMetaType::QVariant
evaluated: value.userType() == where.userType()
TRUEFALSE
yes
Evaluation Count:10
yes
Evaluation Count:6
partially evaluated: mp.userType() == QMetaType::QVariant
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:6
0-10
168 || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) {
partially evaluated: expectedSignature[0] == 'v'
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:6
never evaluated: expectedSignature[1] == '\0'
0-6
169 // simple match -
170 where = value;
executed (the execution status of this line is deduced): where = value;
-
171 return;
executed: return;
Execution Count:10
10
172 } -
173 -
174 if (value.userType() == qMetaTypeId<QDBusArgument>()) {
partially evaluated: value.userType() == qMetaTypeId<QDBusArgument>()
TRUEFALSE
yes
Evaluation Count:6
no
Evaluation Count:0
0-6
175 QDBusArgument arg = qvariant_cast<QDBusArgument>(value);
executed (the execution status of this line is deduced): QDBusArgument arg = qvariant_cast<QDBusArgument>(value);
-
176 -
177 foundType = "user type";
executed (the execution status of this line is deduced): foundType = "user type";
-
178 foundSignature = arg.currentSignature().toLatin1();
executed (the execution status of this line is deduced): foundSignature = arg.currentSignature().toLatin1();
-
179 if (foundSignature == expectedSignature) {
partially evaluated: foundSignature == expectedSignature
TRUEFALSE
yes
Evaluation Count:6
no
Evaluation Count:0
0-6
180 // signatures match, we can demarshall -
181 QDBusMetaType::demarshall(arg, where.userType(), where.data());
executed (the execution status of this line is deduced): QDBusMetaType::demarshall(arg, where.userType(), where.data());
-
182 return;
executed: return;
Execution Count:6
6
183 } -
184 } else {
never executed: }
0
185 foundType = value.typeName();
never executed (the execution status of this line is deduced): foundType = value.typeName();
-
186 foundSignature = QDBusMetaType::typeToSignature(value.userType());
never executed (the execution status of this line is deduced): foundSignature = QDBusMetaType::typeToSignature(value.userType());
-
187 }
never executed: }
0
188 -
189 // there was an error... -
190 QString errmsg = QLatin1String("Unexpected `%1' (%2) when retrieving property `%3.%4' "
never executed (the execution status of this line is deduced): QString errmsg = QLatin1String("Unexpected `%1' (%2) when retrieving property `%3.%4' "
-
191 "(expected type `%5' (%6))");
never executed (the execution status of this line is deduced): "(expected type `%5' (%6))");
-
192 lastError = QDBusError(QDBusError::InvalidSignature,
never executed (the execution status of this line is deduced): lastError = QDBusError(QDBusError::InvalidSignature,
-
193 errmsg.arg(QString::fromLatin1(foundType),
never executed (the execution status of this line is deduced): errmsg.arg(QString::fromLatin1(foundType),
-
194 QString::fromLatin1(foundSignature),
never executed (the execution status of this line is deduced): QString::fromLatin1(foundSignature),
-
195 interface,
never executed (the execution status of this line is deduced): interface,
-
196 QString::fromUtf8(mp.name()),
never executed (the execution status of this line is deduced): QString::fromUtf8(mp.name()),
-
197 QString::fromLatin1(mp.typeName()),
never executed (the execution status of this line is deduced): QString::fromLatin1(mp.typeName()),
-
198 QString::fromLatin1(expectedSignature)));
never executed (the execution status of this line is deduced): QString::fromLatin1(expectedSignature)));
-
199 where.clear();
never executed (the execution status of this line is deduced): where.clear();
-
200 return;
never executed: return;
0
201} -
202 -
203bool QDBusAbstractInterfacePrivate::setProperty(const QMetaProperty &mp, const QVariant &value) -
204{ -
205 if (!isValid || !canMakeCalls()) // can't make calls -
206 return false; -
207 -
208 // send the value -
209 QDBusMessage msg = QDBusMessage::createMethodCall(service, path, -
210 QLatin1String(DBUS_INTERFACE_PROPERTIES), -
211 QLatin1String("Set")); -
212 QDBusMessagePrivate::setParametersValidated(msg, true); -
213 msg << interface << QString::fromUtf8(mp.name()) << QVariant::fromValue(QDBusVariant(value)); -
214 QDBusMessage reply = connection.call(msg, QDBus::Block, timeout); -
215 -
216 if (reply.type() != QDBusMessage::ReplyMessage) { -
217 lastError = QDBusError(reply); -
218 return false; -
219 } -
220 return true; -
221} -
222 -
223void QDBusAbstractInterfacePrivate::_q_serviceOwnerChanged(const QString &name, -
224 const QString &oldOwner, -
225 const QString &newOwner) -
226{ -
227 Q_UNUSED(oldOwner); -
228 //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner; -
229 if (name == service) { -
230 currentOwner = newOwner; -
231 } -
232} -
233 -
234QDBusAbstractInterfaceBase::QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &d, QObject *parent) -
235 : QObject(d, parent) -
236{ -
237} -
238 -
239int QDBusAbstractInterfaceBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a) -
240{ -
241 int saved_id = _id; -
242 _id = QObject::qt_metacall(_c, _id, _a); -
243 if (_id < 0) -
244 return _id; -
245 -
246 if (_c == QMetaObject::ReadProperty || _c == QMetaObject::WriteProperty) { -
247 QMetaProperty mp = metaObject()->property(saved_id); -
248 int &status = *reinterpret_cast<int *>(_a[2]); -
249 QVariant &variant = *reinterpret_cast<QVariant *>(_a[1]); -
250 -
251 if (_c == QMetaObject::WriteProperty) { -
252 status = d_func()->setProperty(mp, variant) ? 1 : 0; -
253 } else { -
254 d_func()->property(mp, variant); -
255 status = variant.isValid() ? 1 : 0; -
256 } -
257 _id = -1; -
258 } -
259 return _id; -
260} -
261 -
262/*!-
\class QDBusAbstractInterface
\inmodule QtDBus
\since 4.2
\brief The QDBusAbstractInterface class is the base class for all D-Bus interfaces in the QtDBus binding, allowing access to remote interfaces
Generated-code classes also derive from QDBusAbstractInterface,
all methods described here are also valid for generated-code
classes. In addition to those described here, generated-code
classes provide member functions for the remote methods, which
allow for compile-time checking of the correct parameters and
return values, as well as property type-matching and signal
parameter-matching.
\sa {qdbusxml2cpp.html}{The QDBus compiler}, QDBusInterface
*/*!
263 \class QDBusAbstractInterface -
264 \inmodule QtDBus -
265 \since 4.2 -
266 -
267 \brief The QDBusAbstractInterface class is the base class for all D-Bus interfaces in the Qt D-Bus binding, allowing access to remote interfaces -
268 -
269 Generated-code classes also derive from QDBusAbstractInterface, -
270 all methods described here are also valid for generated-code -
271 classes. In addition to those described here, generated-code -
272 classes provide member functions for the remote methods, which -
273 allow for compile-time checking of the correct parameters and -
274 return values, as well as property type-matching and signal -
275 parameter-matching. -
276 -
277 \sa {qdbusxml2cpp.html}{The QDBus compiler}, QDBusInterface -
278*/ -
279 -
280/*! -
281 \internal -
282 This is the constructor called from QDBusInterface::QDBusInterface. -
283*/ -
284QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate &d, QObject *parent) -
285 : QDBusAbstractInterfaceBase(d, parent) -
286{ -
287 // keep track of the service owner -
288 if (d.isValid && -
289 d.connection.isConnected() -
290 && !d.service.isEmpty() -
291 && !d.service.startsWith(QLatin1Char(':'))) -
292 d_func()->connection.connect(QLatin1String(DBUS_SERVICE_DBUS), // service -
293 QString(), // path -
294 QLatin1String(DBUS_INTERFACE_DBUS), // interface -
295 QLatin1String("NameOwnerChanged"), -
296 QStringList() << d.service, -
297 QString(), // signature -
298 this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); -
299} -
300 -
301/*! -
302 \internal -
303 This is the constructor called from static classes derived from -
304 QDBusAbstractInterface (i.e., those generated by dbusxml2cpp). -
305*/ -
306QDBusAbstractInterface::QDBusAbstractInterface(const QString &service, const QString &path, -
307 const char *interface, const QDBusConnection &con, -
308 QObject *parent) -
309 : QDBusAbstractInterfaceBase(*new QDBusAbstractInterfacePrivate(service, path, QString::fromLatin1(interface), -
310 con, false), parent) -
311{ -
312 // keep track of the service owner -
313 if (d_func()->isValid && -
314 d_func()->connection.isConnected() -
315 && !service.isEmpty() -
316 && !service.startsWith(QLatin1Char(':'))) -
317 d_func()->connection.connect(QLatin1String(DBUS_SERVICE_DBUS), // service -
318 QString(), // path -
319 QLatin1String(DBUS_INTERFACE_DBUS), // interface -
320 QLatin1String("NameOwnerChanged"), -
321 QStringList() << service, -
322 QString(), //signature -
323 this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); -
324} -
325 -
326/*! -
327 Releases this object's resources. -
328*/ -
329QDBusAbstractInterface::~QDBusAbstractInterface() -
330{ -
331} -
332 -
333/*! -
334 Returns true if this is a valid reference to a remote object. It returns false if -
335 there was an error during the creation of this interface (for instance, if the remote -
336 application does not exist). -
337 -
338 Note: when dealing with remote objects, it is not always possible to determine if it -
339 exists when creating a QDBusInterface. -
340*/ -
341bool QDBusAbstractInterface::isValid() const -
342{ -
343 return !d_func()->currentOwner.isEmpty(); -
344} -
345 -
346/*! -
347 Returns the connection this interface is assocated with. -
348*/ -
349QDBusConnection QDBusAbstractInterface::connection() const -
350{ -
351 return d_func()->connection; -
352} -
353 -
354/*! -
355 Returns the name of the service this interface is associated with. -
356*/ -
357QString QDBusAbstractInterface::service() const -
358{ -
359 return d_func()->service; -
360} -
361 -
362/*! -
363 Returns the object path that this interface is associated with. -
364*/ -
365QString QDBusAbstractInterface::path() const -
366{ -
367 return d_func()->path; -
368} -
369 -
370/*! -
371 Returns the name of this interface. -
372*/ -
373QString QDBusAbstractInterface::interface() const -
374{ -
375 return d_func()->interface; -
376} -
377 -
378/*! -
379 Returns the error the last operation produced, or an invalid error if the last operation did not -
380 produce an error. -
381*/ -
382QDBusError QDBusAbstractInterface::lastError() const -
383{ -
384 return d_func()->lastError; -
385} -
386 -
387/*! -
388 Sets the timeout in milliseconds for all future DBus calls to \a timeout. -
389 -1 means the default DBus timeout (usually 25 seconds). -
390 -
391 \since 4.8 -
392*/ -
393void QDBusAbstractInterface::setTimeout(int timeout) -
394{ -
395 d_func()->timeout = timeout; -
396} -
397 -
398/*! -
399 Returns the current value of the timeout in milliseconds. -
400 -1 means the default DBus timeout (usually 25 seconds). -
401 -
402 \since 4.8 -
403*/ -
404int QDBusAbstractInterface::timeout() const -
405{ -
406 return d_func()->timeout; -
407} -
408 -
409/*! -
410 Places a call to the remote method specified by \a method on this interface, using \a args as -
411 arguments. This function returns the message that was received as a reply, which can be a normal -
412 QDBusMessage::ReplyMessage (indicating success) or QDBusMessage::ErrorMessage (if the call -
413 failed). The \a mode parameter specifies how this call should be placed. -
414 -
415 If the call succeeds, lastError() will be cleared; otherwise, it will contain the error this -
416 call produced. -
417 -
418 Normally, you should place calls using call(). -
419 -
420 \warning If you use \c UseEventLoop, your code must be prepared to deal with any reentrancy: -
421 other method calls and signals may be delivered before this function returns, as well -
422 as other Qt queued signals and events. -
423 -
424 \threadsafe -
425*/ -
426QDBusMessage QDBusAbstractInterface::callWithArgumentList(QDBus::CallMode mode, -
427 const QString& method, -
428 const QList<QVariant>& args) -
429{ -
430 Q_D(QDBusAbstractInterface); -
431 -
432 if (!d->isValid || !d->canMakeCalls()) -
433 return QDBusMessage::createError(d->lastError); -
434 -
435 QString m = method; -
436 // split out the signature from the method -
437 int pos = method.indexOf(QLatin1Char('.')); -
438 if (pos != -1) -
439 m.truncate(pos); -
440 -
441 if (mode == QDBus::AutoDetect) { -
442 // determine if this a sync or async call -
443 mode = QDBus::Block; -
444 const QMetaObject *mo = metaObject(); -
445 QByteArray match = m.toLatin1(); -
446 -
447 for (int i = staticMetaObject.methodCount(); i < mo->methodCount(); ++i) { -
448 QMetaMethod mm = mo->method(i); -
449 if (mm.name() == match) { -
450 // found a method with the same name as what we're looking for -
451 // hopefully, nobody is overloading asynchronous and synchronous methods with -
452 // the same name -
453 -
454 QList<QByteArray> tags = QByteArray(mm.tag()).split(' '); -
455 if (tags.contains("Q_NOREPLY")) -
456 mode = QDBus::NoBlock; -
457 -
458 break; -
459 } -
460 } -
461 } -
462 -
463// qDebug() << "QDBusAbstractInterface" << "Service" << service() << "Path:" << path(); -
464 QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), m); -
465 QDBusMessagePrivate::setParametersValidated(msg, true); -
466 msg.setArguments(args); -
467 -
468 QDBusMessage reply = d->connection.call(msg, mode, d->timeout); -
469 if (thread() == QThread::currentThread()) -
470 d->lastError = QDBusError(reply); // will clear if reply isn't an error -
471 -
472 // ensure that there is at least one element -
473 if (reply.arguments().isEmpty()) -
474 reply << QVariant(); -
475 -
476 return reply; -
477} -
478 -
479/*! -
480 \since 4.5 -
481 Places a call to the remote method specified by \a method on this -
482 interface, using \a args as arguments. This function returns a -
483 QDBusPendingCall object that can be used to track the status of the -
484 reply and access its contents once it has arrived. -
485 -
486 Normally, you should place calls using asyncCall(). -
487 -
488 \threadsafe -
489*/ -
490QDBusPendingCall QDBusAbstractInterface::asyncCallWithArgumentList(const QString& method, -
491 const QList<QVariant>& args) -
492{ -
493 Q_D(QDBusAbstractInterface); -
494 -
495 if (!d->isValid || !d->canMakeCalls()) -
496 return QDBusPendingCall::fromError(d->lastError); -
497 -
498 QDBusMessage msg = QDBusMessage::createMethodCall(service(), path(), interface(), method); -
499 QDBusMessagePrivate::setParametersValidated(msg, true); -
500 msg.setArguments(args); -
501 return d->connection.asyncCall(msg, d->timeout); -
502} -
503 -
504/*! -
505 Places a call to the remote method specified by \a method -
506 on this interface, using \a args as arguments. This function -
507 returns immediately after queueing the call. The reply from -
508 the remote function is delivered to the \a returnMethod on -
509 object \a receiver. If an error occurs, the \a errorMethod -
510 on object \a receiver is called instead. -
511 -
512 This function returns true if the queueing succeeds. It does -
513 not indicate that the executed call succeeded. If it fails, -
514 the \a errorMethod is called. If the queueing failed, this -
515 function returns false and no slot will be called. -
516 -
517 The \a returnMethod must have as its parameters the types returned -
518 by the function call. Optionally, it may have a QDBusMessage -
519 parameter as its last or only parameter. The \a errorMethod must -
520 have a QDBusError as its only parameter. -
521 -
522 \since 4.3 -
523 \sa QDBusError, QDBusMessage -
524 */ -
525bool QDBusAbstractInterface::callWithCallback(const QString &method, -
526 const QList<QVariant> &args, -
527 QObject *receiver, -
528 const char *returnMethod, -
529 const char *errorMethod) -
530{ -
531 Q_D(QDBusAbstractInterface); -
532 -
533 if (!d->isValid || !d->canMakeCalls()) -
534 return false; -
535 -
536 QDBusMessage msg = QDBusMessage::createMethodCall(service(), -
537 path(), -
538 interface(), -
539 method); -
540 QDBusMessagePrivate::setParametersValidated(msg, true); -
541 msg.setArguments(args); -
542 -
543 d->lastError = QDBusError(); -
544 return d->connection.callWithCallback(msg, -
545 receiver, -
546 returnMethod, -
547 errorMethod, -
548 d->timeout); -
549} -
550 -
551/*! -
552 \overload -
553 -
554 This function is deprecated. Please use the overloaded version. -
555 -
556 Places a call to the remote method specified by \a method -
557 on this interface, using \a args as arguments. This function -
558 returns immediately after queueing the call. The reply from -
559 the remote function or any errors emitted by it are delivered -
560 to the \a slot slot on object \a receiver. -
561 -
562 This function returns true if the queueing succeeded: it does -
563 not indicate that the call succeeded. If it failed, the slot -
564 will be called with an error message. lastError() will not be -
565 set under those circumstances. -
566 -
567 \sa QDBusError, QDBusMessage -
568*/ -
569bool QDBusAbstractInterface::callWithCallback(const QString &method, -
570 const QList<QVariant> &args, -
571 QObject *receiver, -
572 const char *slot) -
573{ -
574 return callWithCallback(method, args, receiver, slot, 0); -
575} -
576 -
577/*! -
578 \internal -
579 Catch signal connections. -
580*/ -
581void QDBusAbstractInterface::connectNotify(const QMetaMethod &signal) -
582{ -
583 // someone connecting to one of our signals -
584 Q_D(QDBusAbstractInterface); -
585 if (!d->isValid) -
586 return; -
587 -
588 // we end up recursing here, so optimize away -
589 static const QMetaMethod destroyedSignal = QMetaMethod::fromSignal(&QDBusAbstractInterface::destroyed); -
590 if (signal == destroyedSignal) -
591 return; -
592 -
593 QDBusConnectionPrivate *conn = d->connectionPrivate(); -
594 if (conn) { -
595 conn->connectRelay(d->service, d->path, d->interface, -
596 this, signal); -
597 } -
598} -
599 -
600/*! -
601 \internal -
602 Catch signal disconnections. -
603*/ -
604void QDBusAbstractInterface::disconnectNotify(const QMetaMethod &signal) -
605{ -
606 // someone disconnecting from one of our signals -
607 Q_D(QDBusAbstractInterface); -
608 if (!d->isValid) -
609 return; -
610 -
611 QDBusConnectionPrivate *conn = d->connectionPrivate(); -
612 if (conn) -
613 conn->disconnectRelay(d->service, d->path, d->interface, -
614 this, signal); -
615} -
616 -
617/*! -
618 \internal -
619 Get the value of the property \a propname. -
620*/ -
621QVariant QDBusAbstractInterface::internalPropGet(const char *propname) const -
622{ -
623 // assume this property exists and is readable -
624 // we're only called from generated code anyways -
625 -
626 return property(propname); -
627} -
628 -
629/*! -
630 \internal -
631 Set the value of the property \a propname to \a value. -
632*/ -
633void QDBusAbstractInterface::internalPropSet(const char *propname, const QVariant &value) -
634{ -
635 setProperty(propname, value); -
636} -
637 -
638/*! -
639 Calls the method \a method on this interface and passes the parameters to this function to the -
640 method. -
641 -
642 The parameters to \c call are passed on to the remote function via D-Bus as input -
643 arguments. Output arguments are returned in the QDBusMessage reply. If the reply is an error -
644 reply, lastError() will also be set to the contents of the error message. -
645 -
646 This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2, -
647 \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8 -
648 parameters or if you have a variable number of parameters to be passed, use -
649 callWithArgumentList(). -
650 -
651 It can be used the following way: -
652 -
653 \snippet code/src_qdbus_qdbusabstractinterface.cpp 0 -
654 -
655 This example illustrates function calling with 0, 1 and 2 parameters and illustrates different -
656 parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one -
657 Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array). -
658*/ -
659QDBusMessage QDBusAbstractInterface::call(const QString &method, const QVariant &arg1, -
660 const QVariant &arg2, -
661 const QVariant &arg3, -
662 const QVariant &arg4, -
663 const QVariant &arg5, -
664 const QVariant &arg6, -
665 const QVariant &arg7, -
666 const QVariant &arg8) -
667{ -
668 return call(QDBus::AutoDetect, method, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); -
669} -
670 -
671/*! -
672 \overload -
673 -
674 Calls the method \a method on this interface and passes the -
675 parameters to this function to the method. If \a mode is \c -
676 NoWaitForReply, then this function will return immediately after -
677 placing the call, without waiting for a reply from the remote -
678 method. Otherwise, \a mode indicates whether this function should -
679 activate the Qt Event Loop while waiting for the reply to arrive. -
680 -
681 This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2, -
682 \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8 -
683 parameters or if you have a variable number of parameters to be passed, use -
684 callWithArgumentList(). -
685 -
686 If this function reenters the Qt event loop in order to wait for the -
687 reply, it will exclude user input. During the wait, it may deliver -
688 signals and other method calls to your application. Therefore, it -
689 must be prepared to handle a reentrancy whenever a call is placed -
690 with call(). -
691*/ -
692QDBusMessage QDBusAbstractInterface::call(QDBus::CallMode mode, const QString &method, -
693 const QVariant &arg1, -
694 const QVariant &arg2, -
695 const QVariant &arg3, -
696 const QVariant &arg4, -
697 const QVariant &arg5, -
698 const QVariant &arg6, -
699 const QVariant &arg7, -
700 const QVariant &arg8) -
701{ -
702 QList<QVariant> argList; -
703 int count = 0 + arg1.isValid() + arg2.isValid() + arg3.isValid() + arg4.isValid() + -
704 arg5.isValid() + arg6.isValid() + arg7.isValid() + arg8.isValid(); -
705 -
706 switch (count) { -
707 case 8: -
708 argList.prepend(arg8); -
709 case 7: -
710 argList.prepend(arg7); -
711 case 6: -
712 argList.prepend(arg6); -
713 case 5: -
714 argList.prepend(arg5); -
715 case 4: -
716 argList.prepend(arg4); -
717 case 3: -
718 argList.prepend(arg3); -
719 case 2: -
720 argList.prepend(arg2); -
721 case 1: -
722 argList.prepend(arg1); -
723 } -
724 -
725 return callWithArgumentList(mode, method, argList); -
726} -
727 -
728 -
729/*! -
730 \since 4.5 -
731 Calls the method \a method on this interface and passes the parameters to this function to the -
732 method. -
733 -
734 The parameters to \c call are passed on to the remote function via D-Bus as input -
735 arguments. The returned QDBusPendingCall object can be used to find out information about -
736 the reply. -
737 -
738 This function can be used with up to 8 parameters, passed in arguments \a arg1, \a arg2, -
739 \a arg3, \a arg4, \a arg5, \a arg6, \a arg7 and \a arg8. If you need more than 8 -
740 parameters or if you have a variable number of parameters to be passed, use -
741 asyncCallWithArgumentList(). -
742 -
743 It can be used the following way: -
744 -
745 \snippet code/src_qdbus_qdbusabstractinterface.cpp 1 -
746 -
747 This example illustrates function calling with 0, 1 and 2 parameters and illustrates different -
748 parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one -
749 Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array). -
750*/ -
751QDBusPendingCall QDBusAbstractInterface::asyncCall(const QString &method, const QVariant &arg1, -
752 const QVariant &arg2, -
753 const QVariant &arg3, -
754 const QVariant &arg4, -
755 const QVariant &arg5, -
756 const QVariant &arg6, -
757 const QVariant &arg7, -
758 const QVariant &arg8) -
759{ -
760 QList<QVariant> argList; -
761 int count = 0 + arg1.isValid() + arg2.isValid() + arg3.isValid() + arg4.isValid() + -
762 arg5.isValid() + arg6.isValid() + arg7.isValid() + arg8.isValid(); -
763 -
764 switch (count) { -
765 case 8: -
766 argList.prepend(arg8); -
767 case 7: -
768 argList.prepend(arg7); -
769 case 6: -
770 argList.prepend(arg6); -
771 case 5: -
772 argList.prepend(arg5); -
773 case 4: -
774 argList.prepend(arg4); -
775 case 3: -
776 argList.prepend(arg3); -
777 case 2: -
778 argList.prepend(arg2); -
779 case 1: -
780 argList.prepend(arg1); -
781 } -
782 -
783 return asyncCallWithArgumentList(method, argList); -
784} -
785 -
786/*! -
787 \internal -
788*/ -
789QDBusMessage QDBusAbstractInterface::internalConstCall(QDBus::CallMode mode, -
790 const QString &method, -
791 const QList<QVariant> &args) const -
792{ -
793 // ### move the code here, and make the other functions call this -
794 return const_cast<QDBusAbstractInterface*>(this)->callWithArgumentList(mode, method, args); -
795} -
796 -
797QT_END_NAMESPACE -
798 -
799#endif // QT_NO_DBUS -
800 -
801#include "moc_qdbusabstractinterface.cpp" -
802 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial