src/dbus/qdbusconnectioninterface.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dbus/qdbusconnectioninterface.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,403 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDBus module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdbusconnectioninterface.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QVariant>
+#include <QtCore/QDebug>
+
+#include <qdbus_symbols_p.h>          // for the DBUS_* constants
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * Implementation of interface class QDBusConnectionInterface
+ */
+
+/*!
+    \class QDBusConnectionInterface
+    \inmodule QtDBus
+    \since 4.2
+
+    \brief The QDBusConnectionInterface class provides access to the D-Bus bus daemon service.
+
+    The D-Bus bus server daemon provides one special interface \c
+    org.freedesktop.DBus that allows clients to access certain
+    properties of the bus, such as the current list of clients
+    connected. The QDBusConnectionInterface class provides access to that
+    interface.
+
+    The most common uses of this class are to register and unregister
+    service names on the bus using the registerService() and
+    unregisterService() functions, query about existing names using
+    the isServiceRegistered(), registeredServiceNames() and
+    serviceOwner() functions, and to receive notification that a
+    client has registered or de-registered through the
+    serviceRegistered(), serviceUnregistered() and serviceOwnerChanged()
+    signals.
+*/
+
+/*!
+    \enum QDBusConnectionInterface::ServiceQueueOptions
+
+    Flags for determining how a service registration should behave, in
+    case the service name is already registered.
+
+    \value DontQueueService     If an application requests a name that
+                                is already owned, no queueing will be
+                                performed. The registeredService()
+                                call will simply fail.
+                                This is the default.
+
+    \value QueueService         Attempts to register the requested
+                                service, but do not try to replace it
+                                if another application already has it
+                                registered. Instead, simply put this
+                                application in queue, until it is
+                                given up. The serviceRegistered()
+                                signal will be emitted when that
+                                happens.
+
+    \value ReplaceExistingService If another application already has
+                                the service name registered, attempt
+                                to replace it.
+
+    \sa ServiceReplacementOptions
+*/
+
+/*!
+    \enum QDBusConnectionInterface::ServiceReplacementOptions
+
+    Flags for determining if the D-Bus server should allow another
+    application to replace a name that this application has registered
+    with the ReplaceExistingService option.
+
+    The possible values are:
+
+    \value DontAllowReplacement Do not allow another application to
+                                replace us. The service must be
+                                explicitly unregistered with
+                                unregisterService() for another
+                                application to acquire it.
+                                This is the default.
+
+    \value AllowReplacement     Allow other applications to replace us
+                                with the ReplaceExistingService option
+                                to registerService() without
+                                intervention. If that happens, the
+                                serviceUnregistered() signal will be
+                                emitted.
+
+    \sa ServiceQueueOptions
+*/
+
+/*!
+    \enum QDBusConnectionInterface::RegisterServiceReply
+
+    The possible return values from registerService():
+
+    \value ServiceNotRegistered The call failed and the service name was not registered.
+    \value ServiceRegistered    The caller is now the owner of the service name.
+    \value ServiceQueued        The caller specified the QueueService flag and the
+                                service was already registered, so we are in queue.
+
+    The serviceRegistered() signal will be emitted when the service is
+    acquired by this application.
+*/
+
+/*!
+    \internal
+*/
+const char *QDBusConnectionInterface::staticInterfaceName()
+{ return "org.freedesktop.DBus"; }
+
+/*!
+    \internal
+*/
+QDBusConnectionInterface::QDBusConnectionInterface(const QDBusConnection &connection,
+                                                   QObject *parent)
+    : QDBusAbstractInterface(QLatin1String(DBUS_SERVICE_DBUS),
+                             QLatin1String(DBUS_PATH_DBUS),
+                             DBUS_INTERFACE_DBUS, connection, parent)
+{
+    connect(this, SIGNAL(NameAcquired(QString)), this, SIGNAL(serviceRegistered(QString)));
+    connect(this, SIGNAL(NameLost(QString)), this, SIGNAL(serviceUnregistered(QString)));
+    connect(this, SIGNAL(NameOwnerChanged(QString,QString,QString)),
+            this, SIGNAL(serviceOwnerChanged(QString,QString,QString)));
+}
+
+/*!
+    \internal
+*/
+QDBusConnectionInterface::~QDBusConnectionInterface()
+{
+}
+
+/*!
+    Returns the unique connection name of the primary owner of the
+    name \a name. If the requested name doesn't have an owner, returns
+    a \c org.freedesktop.DBus.Error.NameHasNoOwner error.
+*/
+QDBusReply<QString> QDBusConnectionInterface::serviceOwner(const QString &name) const
+{
+    return internalConstCall(QDBus::AutoDetect, QLatin1String("GetNameOwner"), QList<QVariant>() << name);
+}
+
+/*!
+  \property QDBusConnectionInterface::registeredServiceNames
+  \brief holds the registered service names
+
+  Lists all names currently registered on the bus.
+*/
+QDBusReply<QStringList> QDBusConnectionInterface::registeredServiceNames() const
+{
+    return internalConstCall(QDBus::AutoDetect, QLatin1String("ListNames"));
+}
+
+/*!
+    Returns true if the service name \a serviceName has is currently
+    registered.
+*/
+QDBusReply<bool> QDBusConnectionInterface::isServiceRegistered(const QString &serviceName) const
+{
+    return internalConstCall(QDBus::AutoDetect, QLatin1String("NameHasOwner"),
+                             QList<QVariant>() << serviceName);
+}
+
+/*!
+    Returns the Unix Process ID (PID) for the process currently
+    holding the bus service \a serviceName.
+*/
+QDBusReply<uint> QDBusConnectionInterface::servicePid(const QString &serviceName) const
+{
+    return internalConstCall(QDBus::AutoDetect, QLatin1String("GetConnectionUnixProcessID"),
+                             QList<QVariant>() << serviceName);
+}
+
+/*!
+    Returns the Unix User ID (UID) for the process currently holding
+    the bus service \a serviceName.
+*/
+QDBusReply<uint> QDBusConnectionInterface::serviceUid(const QString &serviceName) const
+{
+    return internalConstCall(QDBus::AutoDetect, QLatin1String("GetConnectionUnixUser"),
+                             QList<QVariant>() << serviceName);
+}
+
+/*!
+    Requests that the bus start the service given by the name \a name.
+*/
+QDBusReply<void> QDBusConnectionInterface::startService(const QString &name)
+{
+    return call(QLatin1String("StartServiceByName"), name, uint(0));
+}
+
+/*!
+    Requests to register the service name \a serviceName on the
+    bus. The \a qoption flag specifies how the D-Bus server should behave
+    if \a serviceName is already registered. The \a roption flag
+    specifies if the server should allow another application to
+    replace our registered name.
+
+    If the service registration succeeds, the serviceRegistered()
+    signal will be emitted. If we are placed in queue, the signal will
+    be emitted when we obtain the name. If \a roption is
+    AllowReplacement, the serviceUnregistered() signal will be emitted
+    if another application replaces this one.
+
+    \sa unregisterService()
+*/
+QDBusReply<QDBusConnectionInterface::RegisterServiceReply>
+QDBusConnectionInterface::registerService(const QString &serviceName,
+                                          ServiceQueueOptions qoption,
+                                          ServiceReplacementOptions roption)
+{
+    // reconstruct the low-level flags
+    uint flags = 0;
+    switch (qoption) {
+    case DontQueueService:
+        flags = DBUS_NAME_FLAG_DO_NOT_QUEUE;
+        break;
+    case QueueService:
+        flags = 0;
+        break;
+    case ReplaceExistingService:
+        flags = DBUS_NAME_FLAG_DO_NOT_QUEUE | DBUS_NAME_FLAG_REPLACE_EXISTING;
+        break;
+    }
+
+    switch (roption) {
+    case DontAllowReplacement:
+        break;
+    case AllowReplacement:
+        flags |= DBUS_NAME_FLAG_ALLOW_REPLACEMENT;
+        break;
+    }
+
+    QDBusMessage reply = call(QLatin1String("RequestName"), serviceName, flags);
+//    qDebug() << "QDBusConnectionInterface::registerService" << serviceName << "Reply:" << reply;
+
+    // convert the low-level flags to something that we can use
+    if (reply.type() == QDBusMessage::ReplyMessage) {
+        uint code = 0;
+
+        switch (reply.arguments().at(0).toUInt()) {
+        case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
+        case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
+            code = uint(ServiceRegistered);
+            break;
+
+        case DBUS_REQUEST_NAME_REPLY_EXISTS:
+            code = uint(ServiceNotRegistered);
+            break;
+
+        case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
+            code = uint(ServiceQueued);
+            break;
+        }
+
+        reply.setArguments(QVariantList() << code);
+    }
+
+    return reply;
+}
+
+/*!
+    Releases the claim on the bus service name \a serviceName, that
+    had been previously registered with registerService(). If this
+    application had ownership of the name, it will be released for
+    other applications to claim. If it only had the name queued, it
+    gives up its position in the queue.
+*/
+QDBusReply<bool>
+QDBusConnectionInterface::unregisterService(const QString &serviceName)
+{
+    QDBusMessage reply = call(QLatin1String("ReleaseName"), serviceName);
+    if (reply.type() == QDBusMessage::ReplyMessage) {
+        bool success = reply.arguments().at(0).toUInt() == DBUS_RELEASE_NAME_REPLY_RELEASED;
+        reply.setArguments(QVariantList() << success);
+    }
+    return reply;
+}
+
+/*!
+    \internal
+*/
+void QDBusConnectionInterface::connectNotify(const char *signalName)
+{
+    // translate the signal names to what we really want
+    // this avoids setting hooks for signals that don't exist on the bus
+    if (qstrcmp(signalName, SIGNAL(serviceRegistered(QString))) == 0)
+        QDBusAbstractInterface::connectNotify(SIGNAL(NameAcquired(QString)));
+
+    else if (qstrcmp(signalName, SIGNAL(serviceUnregistered(QString))) == 0)
+        QDBusAbstractInterface::connectNotify(SIGNAL(NameLost(QString)));
+
+    else if (qstrcmp(signalName, SIGNAL(serviceOwnerChanged(QString,QString,QString))) == 0)
+        QDBusAbstractInterface::connectNotify(SIGNAL(NameOwnerChanged(QString,QString,QString)));
+}
+
+/*!
+    \internal
+*/
+void QDBusConnectionInterface::disconnectNotify(const char *signalName)
+{
+    // translate the signal names to what we really want
+    // this avoids setting hooks for signals that don't exist on the bus
+    if (qstrcmp(signalName, SIGNAL(serviceRegistered(QString))) == 0)
+        QDBusAbstractInterface::disconnectNotify(SIGNAL(NameAcquired(QString)));
+
+    else if (qstrcmp(signalName, SIGNAL(serviceUnregistered(QString))) == 0)
+        QDBusAbstractInterface::disconnectNotify(SIGNAL(NameLost(QString)));
+
+    else if (qstrcmp(signalName, SIGNAL(serviceOwnerChanged(QString,QString,QString))) == 0)
+        QDBusAbstractInterface::disconnectNotify(SIGNAL(NameOwnerChanged(QString,QString,QString)));
+}
+
+// signals
+/*!
+    \fn QDBusConnectionInterface::serviceRegistered(const QString &serviceName)
+
+    This signal is emitted by the D-Bus server when the bus service
+    name (unique connection name or well-known service name) given by
+    \a serviceName is acquired by this application.
+
+    Acquisition happens after this application has requested a name using
+    registerService().
+*/
+
+/*!
+    \fn QDBusConnectionInterface::serviceUnregistered(const QString &serviceName)
+
+    This signal is emitted by the D-Bus server when this application
+    loses ownership of the bus service name given by \a serviceName.
+*/
+
+/*!
+    \fn QDBusConnectionInterface::serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
+
+    This signal is emitted by the D-Bus server whenever a service
+    ownership change happens in the bus, including apparition and
+    disparition of names.
+
+    This signal means the application \a oldOwner lost ownership of
+    bus name \a name to application \a newOwner. If \a oldOwner is an
+    empty string, it means the name \a name has just been created; if
+    \a newOwner is empty, the name \a name has no current owner and is
+    no longer available.
+*/
+
+/*!
+  \fn void QDBusConnectionInterface::callWithCallbackFailed(const QDBusError &error, const QDBusMessage &call)
+
+  This signal is emitted when there is an error during a
+  QDBusConnection::callWithCallback(). \a error specifies the error.
+  \a call is the message that couldn't be delivered.
+
+  \sa QDBusConnection::callWithCallback()
+ */
+
+QT_END_NAMESPACE