[Telepathy-commits] [telepathy-qt4/master] StreamedMediaChannel: Continue implementation (added FeatureStreams support).
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Tue Mar 10 22:44:26 PDT 2009
---
TelepathyQt4/Client/streamed-media-channel.cpp | 297 +++++++++++++++++++++++-
TelepathyQt4/Client/streamed-media-channel.h | 54 +++--
2 files changed, 325 insertions(+), 26 deletions(-)
diff --git a/TelepathyQt4/Client/streamed-media-channel.cpp b/TelepathyQt4/Client/streamed-media-channel.cpp
index 263b63c..90108ee 100644
--- a/TelepathyQt4/Client/streamed-media-channel.cpp
+++ b/TelepathyQt4/Client/streamed-media-channel.cpp
@@ -21,27 +21,198 @@
#include <TelepathyQt4/Client/StreamedMediaChannel>
#include "TelepathyQt4/Client/_gen/streamed-media-channel.moc.hpp"
+
#include "TelepathyQt4/debug-internal.h"
+#include <TelepathyQt4/Client/Connection>
+#include <TelepathyQt4/Client/ContactManager>
+#include <TelepathyQt4/Client/PendingVoidMethodCall>
+
+#include <QHash>
+
namespace Telepathy
{
namespace Client
{
+struct MediaStream::Private
+{
+ Private(StreamedMediaChannel *channel, uint id,
+ uint contactHandle, MediaStreamType type,
+ MediaStreamState state, MediaStreamDirection direction,
+ MediaStreamPendingSend pendingSend)
+ : id(id), contactHandle(contactHandle),
+ type(type), state(state), direction(direction),
+ pendingSend(pendingSend)
+ {
+ }
+
+ StreamedMediaChannel *channel;
+ uint id;
+ uint contactHandle;
+ MediaStreamType type;
+ MediaStreamState state;
+ MediaStreamDirection direction;
+ MediaStreamPendingSend pendingSend;
+};
+
+MediaStream::MediaStream(StreamedMediaChannel *channel, uint id,
+ uint contactHandle, MediaStreamType type,
+ MediaStreamState state, MediaStreamDirection direction,
+ MediaStreamPendingSend pendingSend)
+ : QObject(),
+ mPriv(new Private(channel, id, contactHandle, type,
+ state, direction, pendingSend))
+{
+}
+
+MediaStream::~MediaStream()
+{
+ delete mPriv;
+}
+
+StreamedMediaChannel *MediaStream::channel() const
+{
+ return mPriv->channel;
+}
+
+uint MediaStream::id() const
+{
+ return mPriv->id;
+}
+
+QSharedPointer<Contact> MediaStream::contact() const
+{
+ ContactManager *contactManager = mPriv->channel->connection()->contactManager();
+ return contactManager->lookupContactByHandle(mPriv->contactHandle);
+}
+
+Telepathy::MediaStreamState MediaStream::state() const
+{
+ return mPriv->state;
+}
+
+Telepathy::MediaStreamType MediaStream::type() const
+{
+ return mPriv->type;
+}
+
+bool MediaStream::sending() const
+{
+ return (mPriv->direction & Telepathy::MediaStreamDirectionSend ||
+ mPriv->direction & Telepathy::MediaStreamDirectionBidirectional);
+}
+
+bool MediaStream::receiving() const
+{
+ return (mPriv->direction & Telepathy::MediaStreamDirectionReceive ||
+ mPriv->direction & Telepathy::MediaStreamDirectionBidirectional);
+}
+
+bool MediaStream::localSendingRequested() const
+{
+ return mPriv->pendingSend & MediaStreamPendingLocalSend;
+}
+
+bool MediaStream::remoteSendingRequested() const
+{
+ return mPriv->pendingSend & MediaStreamPendingRemoteSend;
+}
+
+Telepathy::MediaStreamDirection MediaStream::direction() const
+{
+ return mPriv->direction;
+}
+
+Telepathy::MediaStreamPendingSend MediaStream::pendingSend() const
+{
+ return mPriv->pendingSend;
+}
+
+void MediaStream::setDirection(Telepathy::MediaStreamDirection direction,
+ Telepathy::MediaStreamPendingSend pendingSend)
+{
+ mPriv->direction = direction;
+ mPriv->pendingSend = pendingSend;
+ emit directionChanged(direction, pendingSend);
+}
+
+void MediaStream::setState(Telepathy::MediaStreamState state)
+{
+ mPriv->state = state;
+ emit stateChanged(state);
+}
+
+
struct StreamedMediaChannel::Private
{
- inline Private();
- inline ~Private();
+ Private(StreamedMediaChannel *parent);
+ ~Private();
+
+ static void introspectStreams(Private *self);
+
+ // Public object
+ StreamedMediaChannel *parent;
+
+ ReadinessHelper *readinessHelper;
+
+ // Introspection
+ bool initialStreamsReceived;
+
+ QHash<uint, QSharedPointer<MediaStream> > streams;
};
-StreamedMediaChannel::Private::Private()
+StreamedMediaChannel::Private::Private(StreamedMediaChannel *parent)
+ : parent(parent),
+ readinessHelper(parent->readinessHelper()),
+ initialStreamsReceived(false)
{
+ ReadinessHelper::Introspectables introspectables;
+
+ ReadinessHelper::Introspectable introspectableStreams(
+ QSet<uint>() << 0, // makesSenseForStatuses
+ Features() << Channel::FeatureCore, // dependsOnFeatures (core)
+ QStringList(), // dependsOnInterfaces
+ (ReadinessHelper::IntrospectFunc) &Private::introspectStreams,
+ this);
+ introspectables[FeatureStreams] = introspectableStreams;
+
+ readinessHelper->addIntrospectables(introspectables);
}
StreamedMediaChannel::Private::~Private()
{
}
+void StreamedMediaChannel::Private::introspectStreams(StreamedMediaChannel::Private *self)
+{
+ StreamedMediaChannel *parent = self->parent;
+ ChannelTypeStreamedMediaInterface *streamedMediaInterface =
+ parent->streamedMediaInterface();
+
+ parent->connect(streamedMediaInterface,
+ SIGNAL(StreamAdded(uint, uint, uint)),
+ SLOT(onStreamAdded(uint, uint, uint)));
+ parent->connect(streamedMediaInterface,
+ SIGNAL(StreamRemoved(uint)),
+ SLOT(onStreamRemoved(uint)));
+ parent->connect(streamedMediaInterface,
+ SIGNAL(StreamDirectionChanged(uint, uint, uint)),
+ SLOT(onStreamDirectionChanged(uint, uint, uint)));
+ parent->connect(streamedMediaInterface,
+ SIGNAL(StreamStateChanged(uint, uint)),
+ SLOT(onStreamStateChanged(uint, uint)));
+ parent->connect(streamedMediaInterface,
+ SIGNAL(StreamError(uint, uint, const QString &)),
+ SLOT(onStreamError(uint, uint, const QString &)));
+
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
+ streamedMediaInterface->ListStreams(), parent);
+ parent->connect(watcher,
+ SIGNAL(finished(QDBusPendingCallWatcher *)),
+ SLOT(gotStreams(QDBusPendingCallWatcher *)));
+}
+
/**
* \class StreamedMediaChannel
* \ingroup clientchannel
@@ -54,6 +225,8 @@ StreamedMediaChannel::Private::~Private()
* StreamedMedia interface. Until then, it's just a Channel.
*/
+const Feature StreamedMediaChannel::FeatureStreams = Feature(StreamedMediaChannel::staticMetaObject.className(), 0);
+
/**
* Creates a StreamedMediaChannel associated with the given object on the same
* service as the given connection.
@@ -71,7 +244,7 @@ StreamedMediaChannel::StreamedMediaChannel(Connection *connection,
const QVariantMap &immutableProperties,
QObject *parent)
: Channel(connection, objectPath, immutableProperties, parent),
- mPriv(new Private())
+ mPriv(new Private(this))
{
}
@@ -83,6 +256,11 @@ StreamedMediaChannel::~StreamedMediaChannel()
delete mPriv;
}
+MediaStreams StreamedMediaChannel::streams() const
+{
+ return mPriv->streams.values();
+}
+
bool StreamedMediaChannel::awaitingLocalAnswer() const
{
return groupSelfHandleIsLocalPending();
@@ -98,5 +276,116 @@ PendingOperation *StreamedMediaChannel::acceptCall()
return groupAddSelfHandle();
}
+void StreamedMediaChannel::gotStreams(QDBusPendingCallWatcher *watcher)
+{
+ QDBusPendingReply<QVariantMap> reply = *watcher;
+ if (reply.isError()) {
+ warning().nospace() << "StreamedMedia::ListStreams()"
+ " failed with " << reply.error().name() << ": " <<
+ reply.error().message();
+
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams,
+ false, reply.error());
+ return;
+ }
+
+ debug() << "Got reply to StreamedMedia::ListStreams()";
+ mPriv->initialStreamsReceived = true;
+
+ MediaStreamInfoList list = qdbus_cast<MediaStreamInfoList>(reply.value());
+ foreach (const MediaStreamInfo &streamInfo, list) {
+ mPriv->streams.insert(streamInfo.identifier,
+ QSharedPointer<MediaStream>(
+ new MediaStream(this,
+ streamInfo.identifier,
+ streamInfo.contact,
+ (Telepathy::MediaStreamType) streamInfo.type,
+ (Telepathy::MediaStreamState) streamInfo.state,
+ (Telepathy::MediaStreamDirection) streamInfo.direction,
+ (Telepathy::MediaStreamPendingSend) streamInfo.pendingSendFlags)));
+ }
+
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams, true);
+
+ watcher->deleteLater();
+}
+
+void StreamedMediaChannel::onStreamAdded(uint streamId,
+ uint contactHandle, uint streamType)
+{
+ if (mPriv->initialStreamsReceived) {
+ Q_ASSERT(!mPriv->streams.contains(streamId));
+ }
+
+ QSharedPointer<MediaStream> stream = QSharedPointer<MediaStream>(
+ new MediaStream(this, streamId,
+ contactHandle,
+ (Telepathy::MediaStreamType) streamType,
+ // TODO where to get this info from?
+ Telepathy::MediaStreamStateDisconnected,
+ Telepathy::MediaStreamDirectionNone,
+ (Telepathy::MediaStreamPendingSend) 0));
+ mPriv->streams.insert(streamId, stream);
+
+ if (mPriv->initialStreamsReceived) {
+ emit streamAdded(stream);
+ }
+}
+
+void StreamedMediaChannel::onStreamRemoved(uint streamId)
+{
+ if (mPriv->initialStreamsReceived) {
+ Q_ASSERT(mPriv->streams.contains(streamId));
+ }
+
+ if (mPriv->streams.contains(streamId)) {
+ QSharedPointer<MediaStream> stream = mPriv->streams[streamId];
+ emit stream->removed();
+ stream.clear();
+ }
+}
+
+void StreamedMediaChannel::onStreamDirectionChanged(uint streamId,
+ uint streamDirection, uint pendingFlags)
+{
+ if (mPriv->initialStreamsReceived) {
+ Q_ASSERT(mPriv->streams.contains(streamId));
+ }
+
+ if (mPriv->streams.contains(streamId)) {
+ QSharedPointer<MediaStream> stream = mPriv->streams[streamId];
+ stream->setDirection(
+ (Telepathy::MediaStreamDirection) streamDirection,
+ (Telepathy::MediaStreamPendingSend) pendingFlags);
+ }
+}
+
+void StreamedMediaChannel::onStreamStateChanged(uint streamId,
+ uint streamState)
+{
+ if (mPriv->initialStreamsReceived) {
+ Q_ASSERT(mPriv->streams.contains(streamId));
+ }
+
+ if (mPriv->streams.contains(streamId)) {
+ QSharedPointer<MediaStream> stream = mPriv->streams[streamId];
+ stream->setState((Telepathy::MediaStreamState) streamState);
+ }
+}
+
+void StreamedMediaChannel::onStreamError(uint streamId,
+ uint errorCode, const QString &errorMessage)
+{
+ if (mPriv->initialStreamsReceived) {
+ Q_ASSERT(mPriv->streams.contains(streamId));
+ }
+
+ if (mPriv->streams.contains(streamId)) {
+ QSharedPointer<MediaStream> stream = mPriv->streams[streamId];
+ emit stream->error((Telepathy::MediaStreamError) errorCode,
+ errorMessage);
+ }
+}
+
} // Telepathy::Client
} // Telepathy
diff --git a/TelepathyQt4/Client/streamed-media-channel.h b/TelepathyQt4/Client/streamed-media-channel.h
index e15fcf9..ce4d19f 100644
--- a/TelepathyQt4/Client/streamed-media-channel.h
+++ b/TelepathyQt4/Client/streamed-media-channel.h
@@ -39,10 +39,11 @@ class MediaStream : public QObject
Q_OBJECT
Q_DISABLE_COPY(MediaStream)
-#if 0
public:
+ ~MediaStream();
+
StreamedMediaChannel *channel() const;
- uint streamId() const;
+ uint id() const;
QSharedPointer<Contact> contact() const;
Telepathy::MediaStreamState state() const;
@@ -56,36 +57,38 @@ public:
Telepathy::MediaStreamDirection direction() const;
Telepathy::MediaStreamPendingSend pendingSend() const;
-public Q_SLOTS:
+#if 0
PendingOperation *remove();
- PendingOperation *requestStreamDirection(bool send, bool receive);
PendingOperation *requestStreamDirection(
Telepathy::MediaStreamDirection direction);
+#endif
Q_SIGNALS:
- void directionChanged(Telepathy::Client::MediaStream *stream,
- bool sending, bool receiving, bool localSendingRequested,
- bool remoteSendingRequested);
- void error(Telepathy::Client::MediaStream *stream,
- Telepathy::MediaStreamError code, const QString &debugMessage);
- void stateChanged(Telepathy::Client::MediaStream *stream);
- void removed(Telepathy::Client::MediaStream *stream);
+ void removed();
+ void directionChanged(Telepathy::MediaStreamDirection direction,
+ Telepathy::MediaStreamPendingSend pendingSend);
+ void stateChanged(Telepathy::MediaStreamState);
+ void error(Telepathy::MediaStreamError errorCode,
+ const QString &errorMessage);
private:
friend class StreamedMediaChannel;
- MediaStream(StreamedMediaChannel *parent, uint streamId, uint
- contactHandle, MediaStreamType type,
+ MediaStream(StreamedMediaChannel *channel, uint id,
+ uint contactHandle, MediaStreamType type,
MediaStreamState state, MediaStreamDirection direction,
- MediaStreamPendingSend pendingSend) const;
+ MediaStreamPendingSend pendingSend);
+
+ void setDirection(Telepathy::MediaStreamDirection direction,
+ Telepathy::MediaStreamPendingSend pendingSend);
+ void setState(Telepathy::MediaStreamState state);
struct Private;
friend struct Private;
Private *mPriv;
-#endif
};
-typedef QSet<QSharedPointer<MediaStream> > MediaStreams;
+typedef QList<QSharedPointer<MediaStream> > MediaStreams;
class StreamedMediaChannel : public Channel
{
@@ -93,24 +96,20 @@ class StreamedMediaChannel : public Channel
Q_DISABLE_COPY(StreamedMediaChannel)
public:
+ static const Feature FeatureStreams;
+
StreamedMediaChannel(Connection *connection, const QString &objectPath,
const QVariantMap &immutableProperties, QObject *parent = 0);
~StreamedMediaChannel();
-#if 0
-public:
MediaStreams streams() const;
-#endif
-public:
bool awaitingLocalAnswer() const;
bool awaitingRemoteAnswer() const;
-public Q_SLOTS:
PendingOperation *acceptCall();
#if 0
-public Q_SLOTS:
PendingOperation *removeStreams(MediaStreams streams);
PendingOperation *removeStreams(QSet<uint> streams);
@@ -119,6 +118,17 @@ public Q_SLOTS:
QList<Telepathy::MediaStreamType> types);
#endif
+Q_SIGNALS:
+ void streamAdded(const QSharedPointer<MediaStream> &stream);
+
+private Q_SLOTS:
+ void gotStreams(QDBusPendingCallWatcher *);
+ void onStreamAdded(uint, uint, uint);
+ void onStreamRemoved(uint);
+ void onStreamDirectionChanged(uint, uint, uint);
+ void onStreamStateChanged(uint, uint);
+ void onStreamError(uint, uint, const QString &);
+
private:
struct Private;
friend struct Private;
--
1.5.6.5
More information about the telepathy-commits
mailing list