[Telepathy-commits] [telepathy-qt4/master] StreamedMediaChannel: Fixes/improvements.
Andre Moreira Magalhaes (andrunko)
andre.magalhaes at collabora.co.uk
Thu Mar 19 16:29:03 PDT 2009
Do not added MediaStream objects to StreamedMediaChannel until they are ready
(have a contact object).
Make MediaStream a ReadyObject and use this to retrieve the contact (reducing
code complexity).
Changed MediaStream to be a QSharedData in order to use it with
QExplitlySharedDataPointer.
Moved MediaStream signals to StreamedMediaChannel and use the
QExplitlySharedDataPointer<MediaStream> in the signals instead of MediaStream *.
Some other fixes.
Changed call example accordingly.
---
TelepathyQt4/Client/streamed-media-channel.cpp | 369 ++++++++++++++----------
TelepathyQt4/Client/streamed-media-channel.h | 41 ++--
examples/call/call-widget.cpp | 178 +++++++-----
examples/call/call-widget.h | 16 +-
examples/call/call-window.cpp | 5 +-
5 files changed, 346 insertions(+), 263 deletions(-)
diff --git a/TelepathyQt4/Client/streamed-media-channel.cpp b/TelepathyQt4/Client/streamed-media-channel.cpp
index 11ff827..6c71c6f 100644
--- a/TelepathyQt4/Client/streamed-media-channel.cpp
+++ b/TelepathyQt4/Client/streamed-media-channel.cpp
@@ -27,6 +27,7 @@
#include <TelepathyQt4/Client/Connection>
#include <TelepathyQt4/Client/ContactManager>
#include <TelepathyQt4/Client/PendingContacts>
+#include <TelepathyQt4/Client/PendingReady>
#include <TelepathyQt4/Client/PendingVoidMethodCall>
#include <QHash>
@@ -39,37 +40,16 @@ namespace Client
struct PendingMediaStreams::Private
{
Private(PendingMediaStreams *parent, StreamedMediaChannel *channel)
- : parent(parent), channel(channel)
+ : parent(parent), channel(channel), streamsReady(0)
{
}
- Private(PendingMediaStreams *parent, StreamedMediaChannel *channel,
- const MediaStreams &streams)
- : parent(parent), channel(channel), streams(streams)
- {
- getContacts();
- }
-
- void getContacts();
-
PendingMediaStreams *parent;
StreamedMediaChannel *channel;
MediaStreams streams;
+ uint streamsReady;
};
-void PendingMediaStreams::Private::getContacts()
-{
- QSet<uint> contactsRequired;
- foreach (const QSharedPointer<MediaStream> &stream, streams) {
- contactsRequired |= stream->contactHandle();
- }
-
- ContactManager *contactManager = channel->connection()->contactManager();
- parent->connect(contactManager->contactsForHandles(contactsRequired.toList()),
- SIGNAL(finished(Telepathy::Client::PendingOperation *)),
- SLOT(gotContacts(Telepathy::Client::PendingOperation *)));
-}
-
PendingMediaStreams::PendingMediaStreams(StreamedMediaChannel *channel,
ContactPtr contact,
QList<Telepathy::MediaStreamType> types,
@@ -90,14 +70,6 @@ PendingMediaStreams::PendingMediaStreams(StreamedMediaChannel *channel,
SLOT(gotStreams(QDBusPendingCallWatcher*)));
}
-PendingMediaStreams::PendingMediaStreams(StreamedMediaChannel *channel,
- const MediaStreams &streams,
- QObject *parent)
- : PendingOperation(parent),
- mPriv(new Private(this, channel, streams))
-{
-}
-
PendingMediaStreams::~PendingMediaStreams()
{
delete mPriv;
@@ -132,64 +104,72 @@ void PendingMediaStreams::gotStreams(QDBusPendingCallWatcher *watcher)
debug() << "Got reply to StreamedMedia::RequestStreams()";
Telepathy::MediaStreamInfoList list = reply.value();
- QSharedPointer<MediaStream> stream;
+ MediaStreamPtr stream;
foreach (const Telepathy::MediaStreamInfo &streamInfo, list) {
- stream = QSharedPointer<MediaStream>(
- new MediaStream(mPriv->channel,
- streamInfo.identifier,
- streamInfo.contact,
- (Telepathy::MediaStreamType) streamInfo.type,
- (Telepathy::MediaStreamState) streamInfo.state,
- (Telepathy::MediaStreamDirection) streamInfo.direction,
- (Telepathy::MediaStreamPendingSend) streamInfo.pendingSendFlags));
+ stream = mPriv->channel->lookupStreamById(streamInfo.identifier);
+ if (!stream) {
+ stream = MediaStreamPtr(
+ new MediaStream(mPriv->channel,
+ streamInfo.identifier,
+ streamInfo.contact,
+ (Telepathy::MediaStreamType) streamInfo.type,
+ (Telepathy::MediaStreamState) streamInfo.state,
+ (Telepathy::MediaStreamDirection) streamInfo.direction,
+ (Telepathy::MediaStreamPendingSend) streamInfo.pendingSendFlags));
+ mPriv->channel->addStream(stream);
+ }
mPriv->streams.append(stream);
+ connect(mPriv->channel,
+ SIGNAL(streamRemoved(Telepathy::Client::MediaStreamPtr)),
+ SLOT(onStreamRemoved(Telepathy::Client::MediaStreamPtr)));
+ connect(stream->becomeReady(),
+ SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+ SLOT(onStreamReady(Telepathy::Client::PendingOperation*)));
}
- mPriv->getContacts();
-
watcher->deleteLater();
}
-void PendingMediaStreams::gotContacts(PendingOperation *op)
+void PendingMediaStreams::onStreamRemoved(MediaStreamPtr stream)
{
- PendingContacts *pc = qobject_cast<PendingContacts *>(op);
- Q_ASSERT(pc->isForHandles());
-
- if (pc->isError()) {
- warning().nospace() << "Gathering contacts failed: "
- << pc->errorName() << ": " << pc->errorMessage();
+ if (isFinished()) {
+ return;
}
- QHash<uint, ContactPtr> contactsForHandles;
- foreach (const ContactPtr &contact, pc->contacts()) {
- contactsForHandles.insert(contact->handle()[0], contact);
+ if (mPriv->streams.contains(stream)) {
+ // the stream was removed before becoming ready
+ setFinishedWithError(TELEPATHY_ERROR_CANCELLED, "Stream removed before ready");
}
+}
- foreach (uint handle, pc->invalidHandles()) {
- contactsForHandles.insert(handle, ContactPtr());
+void PendingMediaStreams::onStreamReady(PendingOperation *op)
+{
+ if (isFinished()) {
+ return;
}
- foreach (const QSharedPointer<MediaStream> &stream, mPriv->streams) {
- stream->setContact(contactsForHandles[stream->contactHandle()]);
- // make sure the channel has all streams even if StreamAdded was not
- // emitted
- mPriv->channel->addStream(stream);
+ if (op->isError()) {
+ setFinishedWithError(op->errorName(), op->errorMessage());
+ return;
}
- setFinished();
+ mPriv->streamsReady++;
+ if (mPriv->streamsReady == (uint) mPriv->streams.size()) {
+ setFinished();
+ }
}
struct MediaStream::Private
{
- Private(StreamedMediaChannel *channel, uint id,
+ Private(MediaStream *parent, StreamedMediaChannel *channel, uint id,
uint contactHandle, MediaStreamType type,
MediaStreamState state, MediaStreamDirection direction,
- MediaStreamPendingSend pendingSend)
- : channel(channel), id(id), contactHandle(contactHandle), type(type),
- state(state), direction(direction), pendingSend(pendingSend)
- {
- }
+ MediaStreamPendingSend pendingSend);
+ static void introspectContact(Private *self);
+
+ MediaStream *parent;
+ ReadinessHelper *readinessHelper;
StreamedMediaChannel *channel;
uint id;
uint contactHandle;
@@ -200,12 +180,53 @@ struct MediaStream::Private
MediaStreamPendingSend pendingSend;
};
+MediaStream::Private::Private(MediaStream *parent,
+ StreamedMediaChannel *channel, uint id,
+ uint contactHandle, MediaStreamType type,
+ MediaStreamState state, MediaStreamDirection direction,
+ MediaStreamPendingSend pendingSend)
+ : parent(parent),
+ readinessHelper(parent->readinessHelper()),
+ channel(channel),
+ id(id),
+ contactHandle(contactHandle),
+ type(type),
+ state(state),
+ direction(direction),
+ pendingSend(pendingSend)
+{
+ ReadinessHelper::Introspectables introspectables;
+
+ ReadinessHelper::Introspectable introspectableContact(
+ QSet<uint>() << 0, // makesSenseForStatuses
+ Features(), // dependsOnFeatures
+ QStringList(), // dependsOnInterfaces
+ (ReadinessHelper::IntrospectFunc) &Private::introspectContact,
+ this);
+ introspectables[FeatureContact] = introspectableContact;
+
+ readinessHelper->addIntrospectables(introspectables);
+ readinessHelper->becomeReady(FeatureContact);
+}
+
+void MediaStream::Private::introspectContact(MediaStream::Private *self)
+{
+ ContactManager *contactManager = self->channel->connection()->contactManager();
+ self->parent->connect(
+ contactManager->contactsForHandles(UIntList() << self->contactHandle),
+ SIGNAL(finished(Telepathy::Client::PendingOperation *)),
+ SLOT(gotContact(Telepathy::Client::PendingOperation *)));
+}
+
+const Feature MediaStream::FeatureContact = Feature(MediaStream::staticMetaObject.className(), 0);
+
MediaStream::MediaStream(StreamedMediaChannel *channel, uint id,
uint contactHandle, MediaStreamType type,
MediaStreamState state, MediaStreamDirection direction,
MediaStreamPendingSend pendingSend)
: QObject(),
- mPriv(new Private(channel, id, contactHandle, type,
+ ReadyObject(this, 0, FeatureContact),
+ mPriv(new Private(this, channel, id, contactHandle, type,
state, direction, pendingSend))
{
}
@@ -374,26 +395,41 @@ uint MediaStream::contactHandle() const
return mPriv->contactHandle;
}
-void MediaStream::setContact(const ContactPtr &contact)
-{
- Q_ASSERT(!mPriv->contact || mPriv->contact == contact);
- mPriv->contact = contact;
-}
-
void MediaStream::setDirection(Telepathy::MediaStreamDirection direction,
Telepathy::MediaStreamPendingSend pendingSend)
{
mPriv->direction = direction;
mPriv->pendingSend = pendingSend;
- emit directionChanged(this, direction, pendingSend);
}
void MediaStream::setState(Telepathy::MediaStreamState state)
{
mPriv->state = state;
- emit stateChanged(this, state);
}
+void MediaStream::gotContact(PendingOperation *op)
+{
+ PendingContacts *pc = qobject_cast<PendingContacts *>(op);
+ Q_ASSERT(pc->isForHandles());
+
+ if (pc->isError()) {
+ warning().nospace() << "Gathering media stream contact failed: "
+ << pc->errorName() << ": " << pc->errorMessage();
+ }
+
+ QList<ContactPtr> contacts = pc->contacts();
+ UIntList invalidHandles = pc->invalidHandles();
+ if (contacts.size()) {
+ Q_ASSERT(contacts.size() == 1);
+ Q_ASSERT(invalidHandles.size() == 0);
+ mPriv->contact = contacts.first();
+ } else {
+ Q_ASSERT(invalidHandles.size() == 1);
+ warning().nospace() << "Error retrieving media stream contact (invalid handle)";
+ }
+
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureContact, true);
+}
struct StreamedMediaChannel::Private
{
@@ -408,15 +444,14 @@ struct StreamedMediaChannel::Private
ReadinessHelper *readinessHelper;
// Introspection
- bool initialStreamsReceived;
- QHash<uint, QSharedPointer<MediaStream> > streams;
+ QHash<uint, MediaStreamPtr> incompleteStreams;
+ QHash<uint, MediaStreamPtr> streams;
};
StreamedMediaChannel::Private::Private(StreamedMediaChannel *parent)
: parent(parent),
- readinessHelper(parent->readinessHelper()),
- initialStreamsReceived(false)
+ readinessHelper(parent->readinessHelper())
{
ReadinessHelper::Introspectables introspectables;
@@ -553,7 +588,7 @@ PendingOperation *StreamedMediaChannel::acceptCall()
PendingOperation *StreamedMediaChannel::removeStreams(MediaStreams streams)
{
Telepathy::UIntList ids;
- foreach (const QSharedPointer<MediaStream> &stream, streams) {
+ foreach (const MediaStreamPtr &stream, streams) {
ids << stream->id();
}
return removeStreams(ids);
@@ -603,51 +638,56 @@ void StreamedMediaChannel::gotStreams(QDBusPendingCallWatcher *watcher)
debug() << "Got reply to StreamedMedia::ListStreams()";
Telepathy::MediaStreamInfoList list = reply.value();
- foreach (const Telepathy::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)));
+ if (list.size() > 0) {
+ foreach (const Telepathy::MediaStreamInfo &streamInfo, list) {
+ if (!lookupStreamById(streamInfo.identifier)) {
+ addStream(MediaStreamPtr(
+ new MediaStream(this,
+ streamInfo.identifier,
+ streamInfo.contact,
+ (Telepathy::MediaStreamType) streamInfo.type,
+ (Telepathy::MediaStreamState) streamInfo.state,
+ (Telepathy::MediaStreamDirection) streamInfo.direction,
+ (Telepathy::MediaStreamPendingSend) streamInfo.pendingSendFlags)));
+ }
+ }
+ } else {
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams, true);
}
- PendingMediaStreams *pms = new PendingMediaStreams(this,
- mPriv->streams.values(), this);
- connect(pms,
- SIGNAL(finished(Telepathy::Client::PendingOperation *)),
- SLOT(onStreamsReady(Telepathy::Client::PendingOperation *)));
watcher->deleteLater();
}
-void StreamedMediaChannel::onStreamsReady(PendingOperation *op)
+void StreamedMediaChannel::onStreamReady(PendingOperation *op)
{
+ PendingReady *pr = qobject_cast<PendingReady*>(op);
+ MediaStreamPtr stream = MediaStreamPtr(qobject_cast<MediaStream*>(pr->object()));
+
if (op->isError()) {
- mPriv->streams.clear();
- mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams, false,
- op->errorName(), op->errorMessage());
+ mPriv->incompleteStreams.remove(stream->id());
+ // let's not fail because a stream could not become ready
+ if (!isReady(FeatureStreams) && mPriv->incompleteStreams.size() == 0) {
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams, true);
+ }
return;
}
- mPriv->initialStreamsReceived = true;
- mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams, true);
-}
-
-void StreamedMediaChannel::onNewStreamReady(PendingOperation *op)
-{
- PendingMediaStreams *pms = qobject_cast<PendingMediaStreams *>(op);
-
- if (op->isError()) {
+ // the stream was removed before become ready
+ if (!mPriv->incompleteStreams.contains(stream->id())) {
+ if (!isReady(FeatureStreams) && mPriv->incompleteStreams.size() == 0) {
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams, true);
+ }
return;
}
- Q_ASSERT(pms->streams().size() == 1);
+ mPriv->incompleteStreams.remove(stream->id());
+ mPriv->streams.insert(stream->id(), stream);
+
+ if (!isReady(FeatureStreams) && mPriv->incompleteStreams.size() == 0) {
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams, true);
+ }
- if (mPriv->initialStreamsReceived) {
- QSharedPointer<MediaStream> stream = pms->streams().first();
+ if (isReady(FeatureStreams)) {
emit streamAdded(stream);
}
}
@@ -655,26 +695,21 @@ void StreamedMediaChannel::onNewStreamReady(PendingOperation *op)
void StreamedMediaChannel::onStreamAdded(uint streamId,
uint contactHandle, uint streamType)
{
- if (mPriv->streams.contains(streamId)) {
+ if (lookupStreamById(streamId)) {
debug() << "Received StreamedMediaChannel.StreamAdded for an existing "
"stream, ignoring";
return;
}
- QSharedPointer<MediaStream> stream = QSharedPointer<MediaStream>(
+ MediaStreamPtr stream = MediaStreamPtr(
new MediaStream(this, streamId,
contactHandle,
(Telepathy::MediaStreamType) streamType,
// TODO where to get this info from?
- Telepathy::MediaStreamStateConnected,
- (Telepathy::MediaStreamDirection) (Telepathy::MediaStreamDirectionSend | Telepathy::MediaStreamDirectionReceive),
+ Telepathy::MediaStreamStateDisconnected,
+ Telepathy::MediaStreamDirectionNone,
(Telepathy::MediaStreamPendingSend) 0));
- mPriv->streams.insert(streamId, stream);
- PendingMediaStreams *pms = new PendingMediaStreams(this,
- MediaStreams() << stream, this);
- connect(pms,
- SIGNAL(finished(Telepathy::Client::PendingOperation *)),
- SLOT(onNewStreamReady(Telepathy::Client::PendingOperation *)));
+ addStream(stream);
}
void StreamedMediaChannel::onStreamRemoved(uint streamId)
@@ -682,32 +717,43 @@ void StreamedMediaChannel::onStreamRemoved(uint streamId)
debug() << "StreamedMediaChannel::onStreamRemoved: stream" <<
streamId << "removed";
- if (mPriv->initialStreamsReceived) {
- Q_ASSERT(mPriv->streams.contains(streamId));
+ MediaStreamPtr stream = lookupStreamById(streamId);
+ Q_ASSERT(stream);
+ bool incomplete = mPriv->incompleteStreams.contains(streamId);
+ if (incomplete) {
+ mPriv->incompleteStreams.remove(streamId);
+ } else {
+ mPriv->streams.remove(streamId);
+ }
+
+ // the stream was added/removed before become ready
+ if (!isReady(FeatureStreams) &&
+ mPriv->streams.size() == 0 &&
+ mPriv->incompleteStreams.size() == 0) {
+ mPriv->readinessHelper->setIntrospectCompleted(FeatureStreams, true);
}
- if (mPriv->streams.contains(streamId)) {
- QSharedPointer<MediaStream> stream = mPriv->streams[streamId];
- emit stream->removed(stream.data());
- mPriv->streams.remove(streamId);
+ if (isReady(FeatureStreams) && !incomplete) {
+ emit streamRemoved(stream);
}
}
void StreamedMediaChannel::onStreamDirectionChanged(uint streamId,
- uint streamDirection, uint pendingFlags)
+ uint streamDirection, uint streamPendingFlags)
{
debug() << "StreamedMediaChannel::onStreamDirectionChanged: stream" <<
streamId << "direction changed to" << streamDirection;
- if (mPriv->initialStreamsReceived) {
- Q_ASSERT(mPriv->streams.contains(streamId));
- }
-
- if (mPriv->streams.contains(streamId)) {
- QSharedPointer<MediaStream> stream = mPriv->streams[streamId];
- stream->setDirection(
+ MediaStreamPtr stream = lookupStreamById(streamId);
+ Q_ASSERT(stream);
+ stream->setDirection(
+ (Telepathy::MediaStreamDirection) streamDirection,
+ (Telepathy::MediaStreamPendingSend) streamPendingFlags);
+ if (isReady(FeatureStreams) &&
+ !mPriv->incompleteStreams.contains(stream->id())) {
+ emit streamDirectionChanged(stream,
(Telepathy::MediaStreamDirection) streamDirection,
- (Telepathy::MediaStreamPendingSend) pendingFlags);
+ (Telepathy::MediaStreamPendingSend) streamPendingFlags);
}
}
@@ -717,13 +763,13 @@ void StreamedMediaChannel::onStreamStateChanged(uint streamId,
debug() << "StreamedMediaChannel::onStreamStateChanged: stream" <<
streamId << "state changed to" << 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);
+ MediaStreamPtr stream = lookupStreamById(streamId);
+ Q_ASSERT(stream);
+ stream->setState((Telepathy::MediaStreamState) streamState);
+ if (isReady(FeatureStreams) &&
+ !mPriv->incompleteStreams.contains(stream->id())) {
+ emit streamStateChanged(stream,
+ (Telepathy::MediaStreamState) streamState);
}
}
@@ -733,29 +779,32 @@ void StreamedMediaChannel::onStreamError(uint streamId,
debug() << "StreamedMediaChannel::onStreamError: stream" <<
streamId << "error:" << errorCode << "-" << errorMessage;
- if (mPriv->initialStreamsReceived) {
- Q_ASSERT(mPriv->streams.contains(streamId));
- }
-
- if (mPriv->streams.contains(streamId)) {
- QSharedPointer<MediaStream> stream = mPriv->streams[streamId];
- emit stream->error(stream.data(),
- (Telepathy::MediaStreamError) errorCode,
- errorMessage);
+ MediaStreamPtr stream = lookupStreamById(streamId);
+ Q_ASSERT(stream);
+ if (isReady(FeatureStreams) &&
+ !mPriv->incompleteStreams.contains(stream->id())) {
+ emit streamError(stream,
+ (Telepathy::MediaStreamError) errorCode,
+ errorMessage);
}
}
-void StreamedMediaChannel::addStream(const QSharedPointer<MediaStream> &stream)
+void StreamedMediaChannel::addStream(const MediaStreamPtr &stream)
{
- if (mPriv->streams.contains(stream->id())) {
- return;
- }
-
- mPriv->streams.insert(stream->id(), stream);
+ mPriv->incompleteStreams.insert(stream->id(), stream);
+ connect(stream->becomeReady(),
+ SIGNAL(finished(Telepathy::Client::PendingOperation*)),
+ SLOT(onStreamReady(Telepathy::Client::PendingOperation*)));
+}
- if (mPriv->initialStreamsReceived) {
- emit streamAdded(stream);
+MediaStreamPtr StreamedMediaChannel::lookupStreamById(uint streamId)
+{
+ if (mPriv->streams.contains(streamId)) {
+ return mPriv->streams.value(streamId);
+ } else if (mPriv->incompleteStreams.contains(streamId)) {
+ return mPriv->incompleteStreams.value(streamId);
}
+ return MediaStreamPtr();
}
} // Telepathy::Client
diff --git a/TelepathyQt4/Client/streamed-media-channel.h b/TelepathyQt4/Client/streamed-media-channel.h
index 25b0bd5..f28700b 100644
--- a/TelepathyQt4/Client/streamed-media-channel.h
+++ b/TelepathyQt4/Client/streamed-media-channel.h
@@ -36,7 +36,8 @@ namespace Client
class StreamedMediaChannel;
class MediaStream;
-typedef QList<QSharedPointer<MediaStream> > MediaStreams;
+typedef QExplicitlySharedDataPointer<MediaStream> MediaStreamPtr;
+typedef QList<MediaStreamPtr> MediaStreams;
class PendingMediaStreams : public PendingOperation
{
@@ -50,7 +51,8 @@ public:
private Q_SLOTS:
void gotStreams(QDBusPendingCallWatcher *);
- void gotContacts(Telepathy::Client::PendingOperation *);
+ void onStreamRemoved(Telepathy::Client::MediaStreamPtr);
+ void onStreamReady(Telepathy::Client::PendingOperation *);
private:
friend class StreamedMediaChannel;
@@ -68,7 +70,9 @@ private:
Private *mPriv;
};
-class MediaStream : public QObject
+class MediaStream : public QObject,
+ private ReadyObject,
+ public QSharedData
{
Q_OBJECT
Q_DISABLE_COPY(MediaStream)
@@ -97,21 +101,15 @@ public:
PendingOperation *requestStreamDirection(
bool send, bool receive);
-Q_SIGNALS:
- void removed(Telepathy::Client::MediaStream *stream);
- void directionChanged(Telepathy::Client::MediaStream *stream,
- Telepathy::MediaStreamDirection direction,
- Telepathy::MediaStreamPendingSend pendingSend);
- void stateChanged(Telepathy::Client::MediaStream *stream,
- Telepathy::MediaStreamState);
- void error(Telepathy::Client::MediaStream *stream,
- Telepathy::MediaStreamError errorCode,
- const QString &errorMessage);
+private Q_SLOTS:
+ void gotContact(Telepathy::Client::PendingOperation *op);
private:
friend class PendingMediaStreams;
friend class StreamedMediaChannel;
+ static const Feature FeatureContact;
+
MediaStream(StreamedMediaChannel *channel, uint id,
uint contactHandle, MediaStreamType type,
MediaStreamState state, MediaStreamDirection direction,
@@ -158,12 +156,20 @@ public:
QList<Telepathy::MediaStreamType> types);
Q_SIGNALS:
- void streamAdded(const QSharedPointer<Telepathy::Client::MediaStream> &stream);
+ void streamAdded(const Telepathy::Client::MediaStreamPtr &stream);
+ void streamRemoved(const Telepathy::Client::MediaStreamPtr &stream);
+ void streamDirectionChanged(const Telepathy::Client::MediaStreamPtr &stream,
+ Telepathy::MediaStreamDirection direction,
+ Telepathy::MediaStreamPendingSend pendingSend);
+ void streamStateChanged(const Telepathy::Client::MediaStreamPtr &stream,
+ Telepathy::MediaStreamState);
+ void streamError(const Telepathy::Client::MediaStreamPtr &stream,
+ Telepathy::MediaStreamError errorCode,
+ const QString &errorMessage);
private Q_SLOTS:
void gotStreams(QDBusPendingCallWatcher *);
- void onStreamsReady(Telepathy::Client::PendingOperation *);
- void onNewStreamReady(Telepathy::Client::PendingOperation *);
+ void onStreamReady(Telepathy::Client::PendingOperation *);
void onStreamAdded(uint, uint, uint);
void onStreamRemoved(uint);
void onStreamDirectionChanged(uint, uint, uint);
@@ -173,7 +179,8 @@ private Q_SLOTS:
private:
friend class PendingMediaStreams;
- void addStream(const QSharedPointer<MediaStream> &stream);
+ void addStream(const MediaStreamPtr &stream);
+ MediaStreamPtr lookupStreamById(uint streamId);
struct Private;
friend struct Private;
diff --git a/examples/call/call-widget.cpp b/examples/call/call-widget.cpp
index 0bb220a..c12b6e3 100644
--- a/examples/call/call-widget.cpp
+++ b/examples/call/call-widget.cpp
@@ -176,26 +176,38 @@ void CallWidget::onChannelReady(PendingOperation *op)
return;
}
-#if 1
+ connect(mChan,
+ SIGNAL(streamAdded(const Telepathy::Client::MediaStreamPtr &)),
+ SLOT(onStreamAdded(const Telepathy::Client::MediaStreamPtr &)));
+ connect(mChan,
+ SIGNAL(streamRemoved(const Telepathy::Client::MediaStreamPtr &)),
+ SLOT(onStreamRemoved(const Telepathy::Client::MediaStreamPtr &)));
+ connect(mChan,
+ SIGNAL(streamDirectionChanged(const Telepathy::Client::MediaStreamPtr &,
+ Telepathy::MediaStreamDirection,
+ Telepathy::MediaStreamPendingSend)),
+ SLOT(onStreamDirectionChanged(const Telepathy::Client::MediaStreamPtr &,
+ Telepathy::MediaStreamDirection,
+ Telepathy::MediaStreamPendingSend)));
+ connect(mChan,
+ SIGNAL(streamStateChanged(const Telepathy::Client::MediaStreamPtr &,
+ Telepathy::MediaStreamState)),
+ SLOT(onStreamStateChanged(const Telepathy::Client::MediaStreamPtr &,
+ Telepathy::MediaStreamState)));
+
MediaStreams streams = mChan->streams();
qDebug() << "CallWidget::onChannelReady: number of streams:" << streams.size();
- qDebug() << " streams:";
- foreach (const QSharedPointer<MediaStream> &stream, streams) {
- qDebug() << " " <<
- (stream->type() == Telepathy::MediaStreamTypeAudio ? "Audio" : "Video");
- }
-#endif
-
- connect(mChan,
- SIGNAL(streamAdded(const QSharedPointer<Telepathy::Client::MediaStream> &)),
- SLOT(onStreamAdded(const QSharedPointer<Telepathy::Client::MediaStream> &)));
-
- QSharedPointer<MediaStream> stream = streamForType(Telepathy::MediaStreamTypeAudio);
- if (stream) {
- connectStreamSignals(stream);
- onStreamDirectionChanged(stream.data(), stream->direction(),
- stream->pendingSend());
- onStreamStateChanged(stream.data(), stream->state());
+ if (streams.size() > 0) {
+ foreach (const MediaStreamPtr &stream, streams) {
+ qDebug() << " type:" <<
+ (stream->type() == Telepathy::MediaStreamTypeAudio ? "Audio" : "Video");
+ qDebug() << " direction:" << stream->direction();
+ qDebug() << " state:" << stream->state();
+
+ onStreamDirectionChanged(stream, stream->direction(),
+ stream->pendingSend());
+ onStreamStateChanged(stream, stream->state());
+ }
}
mBtnSendAudio->setEnabled(true);
@@ -224,57 +236,78 @@ void CallWidget::onStreamCreated(PendingOperation *op)
qWarning() << "CallWidget::onStreamCreated: unable to create stream:" <<
op->errorName() << "-" << op->errorMessage();
+ QPushButton *btn = 0;
+
// we cannot create the stream for some reason, update buttons
if (!streamForType(Telepathy::MediaStreamTypeAudio)) {
- mBtnSendAudio->setChecked(false);
- }
- if (!streamForType(Telepathy::MediaStreamTypeVideo)) {
- mBtnSendVideo->setChecked(false);
+ btn = mBtnSendAudio;
+ } else if (!streamForType(Telepathy::MediaStreamTypeVideo)) {
+ btn = mBtnSendVideo;
+ } else {
+ Q_ASSERT(false);
}
+
+ btn->blockSignals(true);
+ btn->setChecked(false);
+ btn->blockSignals(false);
return;
}
- PendingMediaStreams *pms = qobject_cast<PendingMediaStreams *>(op);
- Q_ASSERT(pms->streams().size() == 1);
- QSharedPointer<MediaStream> stream = pms->streams().first();
- connectStreamSignals(stream);
- updateStreamDirection(stream);
- onStreamDirectionChanged(stream.data(), stream->direction(),
- stream->pendingSend());
- onStreamStateChanged(stream.data(), stream->state());
+ // do nothing as streamAdded signal will be emitted
}
-void CallWidget::onStreamAdded(const QSharedPointer<MediaStream> &stream)
+void CallWidget::onStreamAdded(const MediaStreamPtr &stream)
{
- connectStreamSignals(stream);
+ qDebug() << "CallWidget::onStreamAdded:" <<
+ (stream->type() == Telepathy::MediaStreamTypeAudio ? "Audio" : "Video") <<
+ "stream created";
+ qDebug() << " direction:" << stream->direction();
+ qDebug() << " state:" << stream->state();
+
updateStreamDirection(stream);
- onStreamDirectionChanged(stream.data(), stream->direction(),
+ onStreamDirectionChanged(stream, stream->direction(),
stream->pendingSend());
- onStreamStateChanged(stream.data(), stream->state());
+ onStreamStateChanged(stream, stream->state());
}
-void CallWidget::onStreamRemoved(MediaStream *stream)
+void CallWidget::onStreamRemoved(const MediaStreamPtr &stream)
{
+ qDebug() << "CallWidget::onStreamRemoved:" <<
+ (stream->type() == Telepathy::MediaStreamTypeAudio ? "Audio" : "Video") <<
+ "stream removed";
if (stream->type() == Telepathy::MediaStreamTypeAudio) {
+ mBtnSendAudio->blockSignals(true);
mBtnSendAudio->setChecked(false);
+ mBtnSendAudio->blockSignals(false);
+ mLblAudioDirection->setText(QLatin1String("Direction: None"));
+ mLblAudioState->setText(QLatin1String("State: Disconnected"));
} else if (stream->type() == Telepathy::MediaStreamTypeVideo) {
+ mBtnSendVideo->blockSignals(true);
mBtnSendVideo->setChecked(false);
+ mBtnSendVideo->blockSignals(false);
+ mLblVideoDirection->setText(QLatin1String("Direction: None"));
+ mLblVideoState->setText(QLatin1String("State: Disconnected"));
}
}
-void CallWidget::onStreamDirectionChanged(MediaStream *stream,
+void CallWidget::onStreamDirectionChanged(const MediaStreamPtr &stream,
Telepathy::MediaStreamDirection direction,
Telepathy::MediaStreamPendingSend pendingSend)
{
- qDebug() << "CallWidget::onStreamDirectionChanged: stream " <<
+ qDebug() << "CallWidget::onStreamDirectionChanged:" <<
(stream->type() == Telepathy::MediaStreamTypeAudio ? "Audio" : "Video") <<
- "direction changed to" << direction;
+ "stream direction changed to" << direction;
- QLabel *lbl;
+ QLabel *lbl = 0;
+ QPushButton *btn = 0;
if (stream->type() == Telepathy::MediaStreamTypeAudio) {
lbl = mLblAudioDirection;
- } else {
+ btn = mBtnSendAudio;
+ } else if (stream->type() == Telepathy::MediaStreamTypeVideo) {
lbl = mLblVideoDirection;
+ btn = mBtnSendVideo;
+ } else {
+ Q_ASSERT(false);
}
if (direction == Telepathy::MediaStreamDirectionSend) {
@@ -286,22 +319,27 @@ void CallWidget::onStreamDirectionChanged(MediaStream *stream,
} else {
lbl->setText(QLatin1String("Direction: None"));
}
+
+ btn->blockSignals(true);
+ btn->setChecked(direction & Telepathy::MediaStreamDirectionSend);
+ btn->blockSignals(false);
}
-void CallWidget::onStreamStateChanged(MediaStream *stream,
+void CallWidget::onStreamStateChanged(const MediaStreamPtr &stream,
Telepathy::MediaStreamState state)
{
- qDebug() << "CallWidget::onStreamStateChanged: stream " <<
+ qDebug() << "CallWidget::onStreamStateChanged:" <<
(stream->type() == Telepathy::MediaStreamTypeAudio ? "Audio" : "Video") <<
- "state changed to" << state;
+ "stream state changed to" << state;
- QLabel *lbl;
+ QLabel *lbl = 0;
if (stream->type() == Telepathy::MediaStreamTypeAudio) {
lbl = mLblAudioState;
- } else {
+ } else if (stream->type() == Telepathy::MediaStreamTypeVideo) {
lbl = mLblVideoState;
+ } else {
+ Q_ASSERT(false);
}
-
if (state == Telepathy::MediaStreamStateDisconnected) {
lbl->setText(QLatin1String("State: Disconnected"));
} else if (state == Telepathy::MediaStreamStateConnecting) {
@@ -335,7 +373,7 @@ void CallWidget::onBtnHangupClicked()
void CallWidget::onBtnSendAudioToggled(bool checked)
{
- QSharedPointer<MediaStream> stream =
+ MediaStreamPtr stream =
streamForType(Telepathy::MediaStreamTypeAudio);
qDebug() << "CallWidget::onBtnSendAudioToggled: checked:" << checked;
if (!stream) {
@@ -354,7 +392,7 @@ void CallWidget::onBtnSendAudioToggled(bool checked)
void CallWidget::onBtnSendVideoToggled(bool checked)
{
- QSharedPointer<MediaStream> stream =
+ MediaStreamPtr stream =
streamForType(Telepathy::MediaStreamTypeVideo);
qDebug() << "CallWidget::onBtnSendVideoToggled: checked:" << checked;
if (!stream) {
@@ -371,54 +409,42 @@ void CallWidget::onBtnSendVideoToggled(bool checked)
}
}
-QSharedPointer<MediaStream> CallWidget::streamForType(Telepathy::MediaStreamType type) const
+MediaStreamPtr CallWidget::streamForType(Telepathy::MediaStreamType type) const
{
MediaStreams streams = mChan->streams();
- foreach (const QSharedPointer<MediaStream> &stream, streams) {
+ foreach (const MediaStreamPtr &stream, streams) {
if (stream->type() == type) {
return stream;
}
}
- return QSharedPointer<MediaStream>();
+ return MediaStreamPtr();
}
-void CallWidget::connectStreamSignals(const QSharedPointer<MediaStream> &stream)
-{
- connect(stream.data(),
- SIGNAL(removed(Telepathy::Client::MediaStream *)),
- SLOT(onStreamRemoved(Telepathy::Client::MediaStream *)));
- connect(stream.data(),
- SIGNAL(directionChanged(Telepathy::Client::MediaStream *,
- Telepathy::MediaStreamDirection,
- Telepathy::MediaStreamPendingSend)),
- SLOT(onStreamDirectionChanged(Telepathy::Client::MediaStream *,
- Telepathy::MediaStreamDirection,
- Telepathy::MediaStreamPendingSend)));
- connect(stream.data(),
- SIGNAL(stateChanged(Telepathy::Client::MediaStream *,
- Telepathy::MediaStreamState)),
- SLOT(onStreamStateChanged(Telepathy::Client::MediaStream *,
- Telepathy::MediaStreamState)));
-}
-
-void CallWidget::updateStreamDirection(const QSharedPointer<MediaStream> &stream)
+void CallWidget::updateStreamDirection(const MediaStreamPtr &stream)
{
bool checked = false;
if (stream->type() == Telepathy::MediaStreamTypeAudio) {
checked = mBtnSendAudio->isChecked();
} else if (stream->type() == Telepathy::MediaStreamTypeVideo) {
checked = mBtnSendVideo->isChecked();
+ } else {
+ Q_ASSERT(false);
}
- qDebug() << "CallWidget::updateStreamDirection: current stream direction:" <<
- stream->direction() << "- checked:" << checked;
+ qDebug() << "CallWidget::updateStreamDirection: updating" <<
+ (stream->type() == Telepathy::MediaStreamTypeAudio ? "audio" : "video") <<
+ "stream direction";
if (checked) {
if (!(stream->direction() & Telepathy::MediaStreamDirectionSend)) {
int dir = stream->direction() | Telepathy::MediaStreamDirectionSend;
stream->requestStreamDirection((Telepathy::MediaStreamDirection) dir);
- qDebug() << "CallWidget::updateStreamDirection: start sending " <<
+ qDebug() << "CallWidget::updateStreamDirection: start sending" <<
(stream->type() == Telepathy::MediaStreamTypeAudio ? "audio" : "video");
+ } else {
+ qDebug() << "CallWidget::updateStreamDirection:" <<
+ (stream->type() == Telepathy::MediaStreamTypeAudio ? "audio" : "video") <<
+ "stream updated";
}
} else {
if (stream->direction() & Telepathy::MediaStreamDirectionSend) {
@@ -426,6 +452,10 @@ void CallWidget::updateStreamDirection(const QSharedPointer<MediaStream> &stream
qDebug() << "CallWidget::updateStreamDirection: stop sending " <<
(stream->type() == Telepathy::MediaStreamTypeAudio ? "audio" : "video");
stream->requestStreamDirection((Telepathy::MediaStreamDirection) dir);
+ } else {
+ qDebug() << "CallWidget::updateStreamDirection:" <<
+ (stream->type() == Telepathy::MediaStreamTypeAudio ? "audio" : "video") <<
+ "stream updated";
}
}
}
diff --git a/examples/call/call-widget.h b/examples/call/call-widget.h
index 1c0b365..e54961e 100644
--- a/examples/call/call-widget.h
+++ b/examples/call/call-widget.h
@@ -21,11 +21,11 @@
#ifndef _TelepathyQt4_examples_call_call_widget_h_HEADER_GUARD_
#define _TelepathyQt4_examples_call_call_widget_h_HEADER_GUARD_
-#include <QSharedPointer>
#include <QWidget>
#include <TelepathyQt4/Client/Channel>
#include <TelepathyQt4/Client/Contact>
+#include <TelepathyQt4/Client/StreamedMediaChannel>
#include <TelepathyQt4/Constants>
#include "farsight-channel.h"
@@ -36,7 +36,6 @@ class DBusProxy;
class MediaStream;
class PendingMediaStreams;
class PendingOperation;
-class StreamedMediaChannel;
}
}
@@ -62,12 +61,12 @@ private Q_SLOTS:
void onChannelInvalidated(Telepathy::Client::DBusProxy *,
const QString &, const QString &);
void onStreamCreated(Telepathy::Client::PendingOperation *);
- void onStreamAdded(const QSharedPointer<Telepathy::Client::MediaStream> &);
- void onStreamRemoved(Telepathy::Client::MediaStream *);
- void onStreamDirectionChanged(Telepathy::Client::MediaStream *,
+ void onStreamAdded(const Telepathy::Client::MediaStreamPtr &);
+ void onStreamRemoved(const Telepathy::Client::MediaStreamPtr &);
+ void onStreamDirectionChanged(const Telepathy::Client::MediaStreamPtr &,
Telepathy::MediaStreamDirection,
Telepathy::MediaStreamPendingSend);
- void onStreamStateChanged(Telepathy::Client::MediaStream *,
+ void onStreamStateChanged(const Telepathy::Client::MediaStreamPtr &,
Telepathy::MediaStreamState);
void onTfChannelStatusChanged(Telepathy::Client::FarsightChannel::Status);
@@ -79,9 +78,8 @@ private:
void createActions();
void setupGui();
- QSharedPointer<Telepathy::Client::MediaStream> streamForType(Telepathy::MediaStreamType type) const;
- void connectStreamSignals(const QSharedPointer<Telepathy::Client::MediaStream> &stream);
- void updateStreamDirection(const QSharedPointer<Telepathy::Client::MediaStream> &stream);
+ Telepathy::Client::MediaStreamPtr streamForType(Telepathy::MediaStreamType type) const;
+ void updateStreamDirection(const Telepathy::Client::MediaStreamPtr &stream);
void callEnded(const QString &message);
diff --git a/examples/call/call-window.cpp b/examples/call/call-window.cpp
index 1e3962f..d3f6dd6 100644
--- a/examples/call/call-window.cpp
+++ b/examples/call/call-window.cpp
@@ -155,8 +155,8 @@ void CallWindow::onNewChannels(const Telepathy::ChannelDetailsList &channels)
foreach (const Telepathy::ChannelDetails &details, channels) {
QString channelType = details.properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".ChannelType")).toString();
bool requested = details.properties.value(QLatin1String(TELEPATHY_INTERFACE_CHANNEL ".Requested")).toBool();
- qDebug() << "CallWindow::onNewChannels: channelType:" << channelType;
- qDebug() << "CallWindow::onNewChannels: requested:" << requested;
+ qDebug() << " channelType:" << channelType;
+ qDebug() << " requested :" << requested;
if (channelType == TELEPATHY_INTERFACE_CHANNEL_TYPE_STREAMED_MEDIA &&
!requested) {
@@ -164,7 +164,6 @@ void CallWindow::onNewChannels(const Telepathy::ChannelDetailsList &channels)
details.channel.path(),
details.properties);
mCallHandler->addIncomingCall(channel);
- qDebug() << "CallWindow::onNewChannels: new call received";
}
}
}
--
1.5.6.5
More information about the telepathy-commits
mailing list