diff options
-rw-r--r-- | TelepathyQt/BaseChannel | 13 | ||||
-rw-r--r-- | TelepathyQt/CMakeLists.txt | 5 | ||||
-rw-r--r-- | TelepathyQt/base-channel-internal.h | 95 | ||||
-rw-r--r-- | TelepathyQt/base-channel.cpp | 342 | ||||
-rw-r--r-- | TelepathyQt/base-channel.h | 110 | ||||
-rw-r--r-- | TelepathyQt/service-types.h | 4 |
6 files changed, 569 insertions, 0 deletions
diff --git a/TelepathyQt/BaseChannel b/TelepathyQt/BaseChannel new file mode 100644 index 00000000..f9eb36a3 --- /dev/null +++ b/TelepathyQt/BaseChannel @@ -0,0 +1,13 @@ +#ifndef _TelepathyQt_BaseChannel_HEADER_GUARD_ +#define _TelepathyQt_BaseChannel_HEADER_GUARD_ + +#ifndef IN_TP_QT_HEADER +#define IN_TP_QT_HEADER +#endif + +#include <TelepathyQt/base-channel.h> + +#undef IN_TP_QT_HEADER + +#endif +// vim:set ft=cpp: diff --git a/TelepathyQt/CMakeLists.txt b/TelepathyQt/CMakeLists.txt index 47ec09c0..55e99faf 100644 --- a/TelepathyQt/CMakeLists.txt +++ b/TelepathyQt/CMakeLists.txt @@ -856,6 +856,7 @@ if(ENABLE_EXPERIMENTAL_SERVICE_SUPPORT) set(telepathy_qt_service_SRCS base-connection-manager.cpp base-connection.cpp + base-channel.cpp base-protocol.cpp dbus-error.cpp dbus-object.cpp @@ -871,6 +872,8 @@ if(ENABLE_EXPERIMENTAL_SERVICE_SUPPORT) base-connection-manager.h BaseConnection base-connection.h + BaseChannel + base-channel.h BaseProtocol BaseProtocolAddressingInterface BaseProtocolAvatarsInterface @@ -896,6 +899,8 @@ if(ENABLE_EXPERIMENTAL_SERVICE_SUPPORT) abstract-adaptor.h base-connection-manager.h base-connection-manager-internal.h + base-channel.h + base-channel-internal.h base-connection.h base-connection-internal.h base-protocol.h diff --git a/TelepathyQt/base-channel-internal.h b/TelepathyQt/base-channel-internal.h new file mode 100644 index 00000000..4b8c807b --- /dev/null +++ b/TelepathyQt/base-channel-internal.h @@ -0,0 +1,95 @@ +/** + * This file is part of TelepathyQt + * + * @copyright Copyright (C) 2013 Matthias Gehre <gehre.matthias@gmail.com> + * @license LGPL 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "TelepathyQt/_gen/svc-channel.h" + +#include <TelepathyQt/Global> +#include <TelepathyQt/MethodInvocationContext> +#include <TelepathyQt/Types> +#include "TelepathyQt/debug-internal.h" + + +namespace Tp +{ + +class TP_QT_NO_EXPORT BaseChannel::Adaptee : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString channelType READ channelType) + Q_PROPERTY(QStringList interfaces READ interfaces) + Q_PROPERTY(uint targetHandle READ targetHandle) + Q_PROPERTY(QString targetID READ targetID) + Q_PROPERTY(uint targetHandleType READ targetHandleType) + Q_PROPERTY(bool requested READ requested) + Q_PROPERTY(uint initiatorHandle READ initiatorHandle) + Q_PROPERTY(QString initiatorID READ initiatorID) +public: + Adaptee(const QDBusConnection &dbusConnection, BaseChannel *cm); + ~Adaptee(); + + QString channelType() const { + return mChannel->channelType(); + } + QStringList interfaces() const; + uint targetHandle() const { + return mChannel->targetHandle(); + } + QString targetID() const { + return mChannel->targetID(); + } + uint targetHandleType() const { + return mChannel->targetHandleType(); + } + bool requested() const { + return mChannel->requested(); + } + uint initiatorHandle() const { + return mChannel->initiatorHandle(); + } + QString initiatorID() const { + return mChannel->initiatorID(); + } + +private Q_SLOTS: + void close(const Tp::Service::ChannelAdaptor::CloseContextPtr &context); + void getChannelType(const Tp::Service::ChannelAdaptor::GetChannelTypeContextPtr &context) { + context->setFinished(channelType()); + } + + void getHandle(const Tp::Service::ChannelAdaptor::GetHandleContextPtr &context) { + context->setFinished(targetHandleType(), targetHandle()); + } + + void getInterfaces(const Tp::Service::ChannelAdaptor::GetInterfacesContextPtr &context) { + context->setFinished(interfaces()); + } + + +public: + BaseChannel *mChannel; + Service::ChannelAdaptor *mAdaptor; + +signals: + void closed(); +}; + +} diff --git a/TelepathyQt/base-channel.cpp b/TelepathyQt/base-channel.cpp new file mode 100644 index 00000000..a5fb5e93 --- /dev/null +++ b/TelepathyQt/base-channel.cpp @@ -0,0 +1,342 @@ +/** + * This file is part of TelepathyQt + * + * @copyright Copyright (C) 2013 Matthias Gehre <gehre.matthias@gmail.com> + * @license LGPL 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <TelepathyQt/BaseChannel> +#include "TelepathyQt/base-channel-internal.h" + +#include "TelepathyQt/_gen/base-channel.moc.hpp" +#include "TelepathyQt/_gen/base-channel-internal.moc.hpp" + +#include "TelepathyQt/debug-internal.h" + +#include <TelepathyQt/BaseConnection> +#include <TelepathyQt/Constants> +#include <TelepathyQt/DBusObject> +#include <TelepathyQt/Utils> +#include <TelepathyQt/AbstractProtocolInterface> +#include <QString> +#include <QVariantMap> + +namespace Tp +{ + +struct TP_QT_NO_EXPORT BaseChannel::Private { + Private(BaseChannel *parent, const QDBusConnection &dbusConnection, BaseConnection* connection, + const QString &channelType, uint targetHandle, uint targetHandleType) + : parent(parent), + connection(connection), + channelType(channelType), + targetHandle(targetHandle), + targetHandleType(targetHandleType), + adaptee(new BaseChannel::Adaptee(dbusConnection, parent)) { + } + + BaseChannel *parent; + BaseConnection* connection; + QString channelType; + QHash<QString, AbstractChannelInterfacePtr> interfaces; + uint targetHandle; + QString targetID; + uint targetHandleType; + bool requested; + uint initiatorHandle; + QString initiatorID; + BaseChannel::Adaptee *adaptee; +}; + + +BaseChannel::Adaptee::Adaptee(const QDBusConnection &dbusConnection, + BaseChannel *channel) + : QObject(channel), + mChannel(channel) +{ + debug() << "Creating service::channelAdaptor for " << channel->dbusObject(); + mAdaptor = new Service::ChannelAdaptor(dbusConnection, this, channel->dbusObject()); +} + +BaseChannel::Adaptee::~Adaptee() +{ +} + +QStringList BaseChannel::Adaptee::interfaces() const +{ + QStringList ret; + foreach(const AbstractChannelInterfacePtr & iface, mChannel->interfaces()) { + if (iface->interfaceName().contains(QLatin1String(".Type."))) + continue; //Do not include "Type" + ret << iface->interfaceName(); + } + return ret; +} + +void BaseChannel::Adaptee::close(const Tp::Service::ChannelAdaptor::CloseContextPtr &context) +{ + //emit after return + QMetaObject::invokeMethod(this, "closed", + Qt::QueuedConnection); + //emit after return + QMetaObject::invokeMethod(mChannel, "closed", + Qt::QueuedConnection); + + context->setFinished(); +} + +/** + * \class BaseChannel + * \ingroup servicecm + * \headerfile TelepathyQt/base-channel.h <TelepathyQt/BaseChannel> + * + * \brief Base class for channel implementations. + * + */ + +BaseChannel::BaseChannel(const QDBusConnection &dbusConnection, + BaseConnection* connection, + const QString &channelType, uint targetHandle, + uint targetHandleType) + : DBusService(dbusConnection), + mPriv(new Private(this, dbusConnection, connection, + channelType, targetHandle, targetHandleType)) +{ +} + +/** + * Class destructor. + */ +BaseChannel::~BaseChannel() +{ + delete mPriv; +} + +/** + * Return a unique name for this channel. + * + * \return A unique name for this channel. + */ +QString BaseChannel::uniqueName() const +{ + return QString(QLatin1String("_%1")).arg((quintptr) this, 0, 16); +} + +bool BaseChannel::registerObject(DBusError *error) +{ + if (isRegistered()) { + return true; + } + + QString name = uniqueName(); + QString busName = mPriv->connection->busName(); + //QString busName = QString(QLatin1String("%1.%2")) + // .arg(mPriv->connection->busName(),name); + QString objectPath = QString(QLatin1String("%1/%2")) + .arg(mPriv->connection->objectPath(), name); + debug() << "Registering channel: busName: " << busName << " objectName: " << objectPath; + DBusError _error; + + debug() << "Channel: registering interfaces at " << dbusObject(); + foreach(const AbstractChannelInterfacePtr & iface, mPriv->interfaces) { + if (!iface->registerInterface(dbusObject())) { + // lets not fail if an optional interface fails registering, lets warn only + warning() << "Unable to register interface" << iface->interfaceName(); + } + } + + bool ret = registerObject(busName, objectPath, &_error); + if (!ret && error) { + error->set(_error.name(), _error.message()); + } + return ret; +} + +/** + * Reimplemented from DBusService. + */ +bool BaseChannel::registerObject(const QString &busName, + const QString &objectPath, DBusError *error) +{ + return DBusService::registerObject(busName, objectPath, error); +} + +QString BaseChannel::channelType() const +{ + return mPriv->channelType; +} +QList<AbstractChannelInterfacePtr> BaseChannel::interfaces() const +{ + return mPriv->interfaces.values(); +} +uint BaseChannel::targetHandle() const +{ + return mPriv->targetHandle; +} +QString BaseChannel::targetID() const +{ + return mPriv->targetID; +} +uint BaseChannel::targetHandleType() const +{ + return mPriv->targetHandleType; +} +bool BaseChannel::requested() const +{ + return mPriv->requested; +} +uint BaseChannel::initiatorHandle() const +{ + return mPriv->initiatorHandle; +} +QString BaseChannel::initiatorID() const +{ + return mPriv->initiatorID; +} + +void BaseChannel::setInitiatorHandle(uint initiatorHandle) +{ + mPriv->initiatorHandle = initiatorHandle; +} + +void BaseChannel::setInitiatorID(const QString &initiatorID) +{ + mPriv->initiatorID = initiatorID; +} + +void BaseChannel::setTargetID(const QString &targetID) +{ + mPriv->targetID = targetID; +} + +void BaseChannel::setRequested(bool requested) +{ + mPriv->requested = requested; +} + +/** + * Return the immutable properties of this channel object. + * + * Immutable properties cannot change after the object has been registered + * on the bus with registerObject(). + * + * \return The immutable properties of this channel object. + */ +QVariantMap BaseChannel::immutableProperties() const +{ + QVariantMap map; + map.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType"), + QVariant::fromValue(mPriv->adaptee->channelType())); + map.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandle"), + QVariant::fromValue(mPriv->adaptee->targetHandle())); + map.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".Interfaces"), + QVariant::fromValue(mPriv->adaptee->interfaces())); + map.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetID"), + QVariant::fromValue(mPriv->adaptee->targetID())); + map.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType"), + QVariant::fromValue(mPriv->adaptee->targetHandleType())); + map.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".Requested"), + QVariant::fromValue(mPriv->adaptee->requested())); + map.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".InitiatorHandle"), + QVariant::fromValue(mPriv->adaptee->initiatorHandle())); + map.insert(TP_QT_IFACE_CHANNEL + QLatin1String(".InitiatorID"), + QVariant::fromValue(mPriv->adaptee->initiatorID())); + return map; +} + +Tp::ChannelDetails BaseChannel::details() const +{ + Tp::ChannelDetails details; + details.channel = QDBusObjectPath(objectPath()); + details.properties.unite(immutableProperties()); + + foreach(const AbstractChannelInterfacePtr & iface, mPriv->interfaces) { + details.properties.unite(iface->immutableProperties()); + } + + return details; +} + +/** + * Return a pointer to the interface with the given name. + * + * \param interfaceName The D-Bus name of the interface, + * ex. TP_QT_IFACE_PROTOCOL_INTERFACE_ADDRESSING. + * \return A pointer to the AbstractProtocolInterface object that implements + * the D-Bus interface with the given name, or a null pointer if such an interface + * has not been plugged into this object. + * \sa plugInterface(), interfaces() + */ +AbstractChannelInterfacePtr BaseChannel::interface(const QString &interfaceName) const +{ + return mPriv->interfaces.value(interfaceName); +} + +/** + * Plug a new interface into this Protocol D-Bus object. + * + * This property is immutable and cannot change after this Protocol + * object has been registered on the bus with registerObject(). + * + * \param interface An AbstractProtocolInterface instance that implements + * the interface that is to be plugged. + * \return \c true on success or \c false otherwise + * \sa interfaces(), interface() + */ +bool BaseChannel::plugInterface(const AbstractChannelInterfacePtr &interface) +{ + if (isRegistered()) { + warning() << "Unable to plug protocol interface " << interface->interfaceName() << + "- protocol already registered"; + return false; + } + + if (interface->isRegistered()) { + warning() << "Unable to plug protocol interface" << interface->interfaceName() << + "- interface already registered"; + return false; + } + + if (mPriv->interfaces.contains(interface->interfaceName())) { + warning() << "Unable to plug protocol interface" << interface->interfaceName() << + "- another interface with same name already plugged"; + return false; + } + + debug() << "Interface" << interface->interfaceName() << "plugged"; + mPriv->interfaces.insert(interface->interfaceName(), interface); + return true; +} + +/** + * \class AbstractChannelInterface + * \ingroup servicecm + * \headerfile TelepathyQt/base-channel.h <TelepathyQt/BaseChannel> + * + * \brief Base class for all the Channel object interface implementations. + */ + +AbstractChannelInterface::AbstractChannelInterface(const QString &interfaceName) + : AbstractDBusServiceInterface(interfaceName) +{ +} + +AbstractChannelInterface::~AbstractChannelInterface() +{ +} + +} diff --git a/TelepathyQt/base-channel.h b/TelepathyQt/base-channel.h new file mode 100644 index 00000000..b9911a6e --- /dev/null +++ b/TelepathyQt/base-channel.h @@ -0,0 +1,110 @@ +/** + * This file is part of TelepathyQt + * + * @copyright Copyright (C) 2013 Matthias Gehre <gehre.matthias@gmail.com> + * @license LGPL 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _TelepathyQt_base_channel_h_HEADER_GUARD_ +#define _TelepathyQt_base_channel_h_HEADER_GUARD_ + +#ifndef IN_TP_QT_HEADER +#error IN_TP_QT_HEADER +#endif + +#include <TelepathyQt/DBusService> +#include <TelepathyQt/Global> +#include <TelepathyQt/Types> +#include <TelepathyQt/Callbacks> + +#include <QDBusConnection> + +class QString; + +namespace Tp +{ + +class BaseChannel : public DBusService +{ + Q_OBJECT + Q_DISABLE_COPY(BaseChannel) + +public: + static BaseChannelPtr create(BaseConnection* connection, const QString &channelType, + uint targetHandle, uint targetHandleType) { + return BaseChannelPtr(new BaseChannel(QDBusConnection::sessionBus(), connection, + channelType, targetHandle, targetHandleType)); + } + + virtual ~BaseChannel(); + + QVariantMap immutableProperties() const; + bool registerObject(DBusError *error = NULL); + virtual QString uniqueName() const; + + QString channelType() const; + QList<AbstractChannelInterfacePtr> interfaces() const; + AbstractChannelInterfacePtr interface(const QString &interfaceName) const; + uint targetHandle() const; + QString targetID() const; + uint targetHandleType() const; + bool requested() const; + uint initiatorHandle() const; + QString initiatorID() const; + Tp::ChannelDetails details() const; + + void setInitiatorHandle(uint initiatorHandle); + void setInitiatorID(const QString &initiatorID); + void setTargetID(const QString &targetID); + void setRequested(bool requested); + + bool plugInterface(const AbstractChannelInterfacePtr &interface); + +Q_SIGNALS: + void closed(); +protected: + BaseChannel(const QDBusConnection &dbusConnection, BaseConnection* connection, + const QString &channelType, uint targetHandle, uint targetHandleType); + virtual bool registerObject(const QString &busName, const QString &objectPath, + DBusError *error); +private: + class Adaptee; + friend class Adaptee; + class Private; + friend class Private; + Private *mPriv; +}; + +class TP_QT_EXPORT AbstractChannelInterface : public AbstractDBusServiceInterface +{ + Q_OBJECT + Q_DISABLE_COPY(AbstractChannelInterface) + +public: + AbstractChannelInterface(const QString &interfaceName); + virtual ~AbstractChannelInterface(); + +private: + friend class BaseChannel; + + class Private; + friend class Private; + Private *mPriv; +}; + +} +#endif diff --git a/TelepathyQt/service-types.h b/TelepathyQt/service-types.h index 5c33bd43..cdb8e052 100644 --- a/TelepathyQt/service-types.h +++ b/TelepathyQt/service-types.h @@ -33,23 +33,27 @@ namespace Tp { class AbstractProtocolInterface; +class AbstractChannelInterface; class BaseConnection; class BaseConnectionManager; class BaseProtocol; class BaseProtocolAddressingInterface; class BaseProtocolAvatarsInterface; class BaseProtocolPresenceInterface; +class BaseChannel; class DBusService; #ifndef DOXYGEN_SHOULD_SKIP_THIS typedef SharedPtr<AbstractProtocolInterface> AbstractProtocolInterfacePtr; +typedef SharedPtr<AbstractChannelInterface> AbstractChannelInterfacePtr; typedef SharedPtr<BaseConnection> BaseConnectionPtr; typedef SharedPtr<BaseConnectionManager> BaseConnectionManagerPtr; typedef SharedPtr<BaseProtocol> BaseProtocolPtr; typedef SharedPtr<BaseProtocolAddressingInterface> BaseProtocolAddressingInterfacePtr; typedef SharedPtr<BaseProtocolAvatarsInterface> BaseProtocolAvatarsInterfacePtr; typedef SharedPtr<BaseProtocolPresenceInterface> BaseProtocolPresenceInterfacePtr; +typedef SharedPtr<BaseChannel> BaseChannelPtr; typedef SharedPtr<DBusService> DBusServicePtr; #endif /* DOXYGEN_SHOULD_SKIP_THIS */ |