/**
* This file is part of TelepathyQt
*
* @copyright Copyright (C) 2012 Collabora Ltd.
* @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
#include "TelepathyQt/_gen/pending-dbus-tube-connection.moc.hpp"
#include "TelepathyQt/debug-internal.h"
#include
#include
#include
#include
namespace Tp
{
struct TP_QT_NO_EXPORT PendingDBusTubeConnection::Private
{
Private(PendingDBusTubeConnection *parent);
// Public object
PendingDBusTubeConnection *parent;
DBusTubeChannelPtr tube;
bool allowOtherUsers;
QVariantMap parameters;
};
PendingDBusTubeConnection::Private::Private(PendingDBusTubeConnection *parent)
: parent(parent),
allowOtherUsers(false)
{
}
/**
* \class PendingDBusTubeConnection
* \ingroup clientchannel
* \headerfile TelepathyQt/pending-dbus-tube-connection.h
*
* A pending operation for accepting or offering a DBus tube
*
* This class represents an asynchronous operation for accepting or offering a DBus tube.
* Upon completion, the address of the opened tube is returned as a QString.
*/
PendingDBusTubeConnection::PendingDBusTubeConnection(
PendingString* string,
bool allowOtherUsers,
const QVariantMap& parameters,
const DBusTubeChannelPtr& object)
: PendingOperation(object)
, mPriv(new Private(this))
{
mPriv->tube = object;
mPriv->allowOtherUsers = allowOtherUsers;
mPriv->parameters = parameters;
connect(mPriv->tube.data(), SIGNAL(invalidated(Tp::DBusProxy*,QString,QString)),
this, SLOT(onChannelInvalidated(Tp::DBusProxy*,QString,QString)));
if (string->isFinished()) {
onConnectionFinished(string);
} else {
// Connect the pending void
connect(string, SIGNAL(finished(Tp::PendingOperation*)),
this, SLOT(onConnectionFinished(Tp::PendingOperation*)));
}
}
PendingDBusTubeConnection::PendingDBusTubeConnection(
const QString &errorName,
const QString &errorMessage,
const DBusTubeChannelPtr &object)
: PendingOperation(object)
, mPriv(new PendingDBusTubeConnection::Private(this))
{
setFinishedWithError(errorName, errorMessage);
}
/**
* Class destructor
*/
PendingDBusTubeConnection::~PendingDBusTubeConnection()
{
delete mPriv;
}
/**
* When the operation has been completed successfully, returns the address of the opened DBus connection.
*
* Please note this function will return a meaningful value only if the operation has already
* been completed successfully: in case of failure or non-completion, an empty QString will be
* returned.
*
* \note If you plan to use QtDBus for the DBus connection, please note you should always use
* QDBusConnection::connectToPeer(), regardless of the fact this tube is a p2p or a group one.
* The above function has been introduced in Qt 4.8, previous versions of Qt do not allow the use
* of DBus Tubes through QtDBus.
*
* \returns The address of the opened DBus connection.
*/
QString PendingDBusTubeConnection::address() const
{
return mPriv->tube->address();
}
/**
* Return whether this tube allows other users more than the current one to connect to the
* private bus created by the tube.
*
* Note that even if the tube was accepted or offered specifying not to allow other users, this
* method might still return true if one of the ends did not support such a restriction.
*
* In fact, if one of the ends does not support current user restriction,
* the tube will be offered regardless, falling back to allowing any connection. If your
* application requires strictly this condition to be enforced, you should check
* DBusTubeChannel::supportsRestrictingToCurrentUser before offering the tube,
* and take action from there.
*
* This function, however, is guaranteed to return the same value of the given allowOtherUsers
* parameter when accepting or offering a tube if supportsRestrictingToCurrentUser is true.
*
* \return \c true if any user is allow to connect, \c false otherwise.
*/
bool PendingDBusTubeConnection::allowsOtherUsers() const
{
return mPriv->allowOtherUsers;
}
void PendingDBusTubeConnection::onConnectionFinished(PendingOperation *op)
{
if (isFinished()) {
// The operation has already failed
return;
}
if (op->isError()) {
// Fail
setFinishedWithError(op->errorName(), op->errorMessage());
return;
}
debug() << "Accept/Offer tube finished successfully";
// Now get the address and set it
PendingString *ps = qobject_cast(op);
debug() << "Got address " << ps->result();
mPriv->tube->setAddress(ps->result());
// It might have been already opened - check
if (mPriv->tube->state() == TubeChannelStateOpen) {
onStateChanged(mPriv->tube->state());
} else {
// Wait until the tube gets opened on the other side
connect(mPriv->tube.data(), SIGNAL(stateChanged(Tp::TubeChannelState)),
this, SLOT(onStateChanged(Tp::TubeChannelState)));
}
}
void PendingDBusTubeConnection::onStateChanged(TubeChannelState state)
{
debug() << "Tube state changed to " << state;
if (state == TubeChannelStateOpen) {
if (!mPriv->parameters.isEmpty()) {
// Inject the parameters into the tube
mPriv->tube->setParameters(mPriv->parameters);
}
// The tube is ready: mark the operation as finished
setFinished();
}
}
void PendingDBusTubeConnection::onChannelInvalidated(DBusProxy* proxy,
const QString& errorName, const QString& errorMessage)
{
Q_UNUSED(proxy);
if (isFinished()) {
// The operation has already finished
return;
}
setFinishedWithError(errorName, errorMessage);
}
}