Commit c1c205b7 authored by Yoann Lopes's avatar Yoann Lopes
Browse files

Android: fix QMediaPlayer's state and mediaStatus signals.


Emit signals only after both properties are written to avoid having
incoherent values in signal handlers.

Task-number: QTBUG-40314
Change-Id: I6c8445e61cccf1a9803647329c4fa1f0e452f56d
Reviewed-by: default avatarChristian Stromme <christian.stromme@digia.com>
Showing with 53 additions and 3 deletions
...@@ -37,6 +37,36 @@ ...@@ -37,6 +37,36 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class StateChangeNotifier
{
public:
StateChangeNotifier(QAndroidMediaPlayerControl *mp)
: mControl(mp)
, mPreviousState(mp->state())
, mPreviousMediaStatus(mp->mediaStatus())
{
++mControl->mActiveStateChangeNotifiers;
}
~StateChangeNotifier()
{
if (--mControl->mActiveStateChangeNotifiers)
return;
if (mPreviousState != mControl->state())
Q_EMIT mControl->stateChanged(mControl->state());
if (mPreviousMediaStatus != mControl->mediaStatus())
Q_EMIT mControl->mediaStatusChanged(mControl->mediaStatus());
}
private:
QAndroidMediaPlayerControl *mControl;
QMediaPlayer::State mPreviousState;
QMediaPlayer::MediaStatus mPreviousMediaStatus;
};
QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent) QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
: QMediaPlayerControl(parent), : QMediaPlayerControl(parent),
mMediaPlayer(new AndroidMediaPlayer), mMediaPlayer(new AndroidMediaPlayer),
...@@ -55,7 +85,8 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent) ...@@ -55,7 +85,8 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
mPendingPosition(-1), mPendingPosition(-1),
mPendingSetMedia(false), mPendingSetMedia(false),
mPendingVolume(-1), mPendingVolume(-1),
mPendingMute(-1) mPendingMute(-1),
mActiveStateChangeNotifiers(0)
{ {
connect(mMediaPlayer,SIGNAL(bufferingChanged(qint32)), connect(mMediaPlayer,SIGNAL(bufferingChanged(qint32)),
this,SLOT(onBufferingChanged(qint32))); this,SLOT(onBufferingChanged(qint32)));
...@@ -138,6 +169,8 @@ void QAndroidMediaPlayerControl::setPosition(qint64 position) ...@@ -138,6 +169,8 @@ void QAndroidMediaPlayerControl::setPosition(qint64 position)
return; return;
} }
StateChangeNotifier notifier(this);
if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia) if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia)
setMediaStatus(QMediaPlayer::LoadedMedia); setMediaStatus(QMediaPlayer::LoadedMedia);
...@@ -275,6 +308,8 @@ const QIODevice *QAndroidMediaPlayerControl::mediaStream() const ...@@ -275,6 +308,8 @@ const QIODevice *QAndroidMediaPlayerControl::mediaStream() const
void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent, void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
QIODevice *stream) QIODevice *stream)
{ {
StateChangeNotifier notifier(this);
const bool reloading = (mMediaContent == mediaContent); const bool reloading = (mMediaContent == mediaContent);
if (!reloading) { if (!reloading) {
...@@ -346,6 +381,8 @@ void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput) ...@@ -346,6 +381,8 @@ void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput)
void QAndroidMediaPlayerControl::play() void QAndroidMediaPlayerControl::play()
{ {
StateChangeNotifier notifier(this);
// We need to prepare the mediaplayer again. // We need to prepare the mediaplayer again.
if ((mState & AndroidMediaPlayer::Stopped) && !mMediaContent.isNull()) { if ((mState & AndroidMediaPlayer::Stopped) && !mMediaContent.isNull()) {
setMedia(mMediaContent, mMediaStream); setMedia(mMediaContent, mMediaStream);
...@@ -366,6 +403,8 @@ void QAndroidMediaPlayerControl::play() ...@@ -366,6 +403,8 @@ void QAndroidMediaPlayerControl::play()
void QAndroidMediaPlayerControl::pause() void QAndroidMediaPlayerControl::pause()
{ {
StateChangeNotifier notifier(this);
setState(QMediaPlayer::PausedState); setState(QMediaPlayer::PausedState);
if ((mState & (AndroidMediaPlayer::Started if ((mState & (AndroidMediaPlayer::Started
...@@ -380,6 +419,8 @@ void QAndroidMediaPlayerControl::pause() ...@@ -380,6 +419,8 @@ void QAndroidMediaPlayerControl::pause()
void QAndroidMediaPlayerControl::stop() void QAndroidMediaPlayerControl::stop()
{ {
StateChangeNotifier notifier(this);
setState(QMediaPlayer::StoppedState); setState(QMediaPlayer::StoppedState);
if ((mState & (AndroidMediaPlayer::Prepared if ((mState & (AndroidMediaPlayer::Prepared
...@@ -397,6 +438,8 @@ void QAndroidMediaPlayerControl::stop() ...@@ -397,6 +438,8 @@ void QAndroidMediaPlayerControl::stop()
void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra) void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
{ {
StateChangeNotifier notifier(this);
Q_UNUSED(extra); Q_UNUSED(extra);
switch (what) { switch (what) {
case AndroidMediaPlayer::MEDIA_INFO_UNKNOWN: case AndroidMediaPlayer::MEDIA_INFO_UNKNOWN:
...@@ -428,6 +471,8 @@ void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra) ...@@ -428,6 +471,8 @@ void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra) void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
{ {
StateChangeNotifier notifier(this);
QString errorString; QString errorString;
QMediaPlayer::Error error = QMediaPlayer::ResourceError; QMediaPlayer::Error error = QMediaPlayer::ResourceError;
...@@ -480,6 +525,8 @@ void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra) ...@@ -480,6 +525,8 @@ void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onBufferingChanged(qint32 percent) void QAndroidMediaPlayerControl::onBufferingChanged(qint32 percent)
{ {
StateChangeNotifier notifier(this);
mBuffering = percent != 100; mBuffering = percent != 100;
mBufferPercent = percent; mBufferPercent = percent;
...@@ -511,6 +558,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state) ...@@ -511,6 +558,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
return; return;
} }
StateChangeNotifier notifier(this);
mState = state; mState = state;
switch (mState) { switch (mState) {
case AndroidMediaPlayer::Idle: case AndroidMediaPlayer::Idle:
...@@ -599,7 +648,6 @@ void QAndroidMediaPlayerControl::setState(QMediaPlayer::State state) ...@@ -599,7 +648,6 @@ void QAndroidMediaPlayerControl::setState(QMediaPlayer::State state)
return; return;
mCurrentState = state; mCurrentState = state;
Q_EMIT stateChanged(mCurrentState);
} }
void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status) void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status)
...@@ -614,7 +662,6 @@ void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status ...@@ -614,7 +662,6 @@ void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status
Q_EMIT durationChanged(duration()); Q_EMIT durationChanged(duration());
mCurrentMediaStatus = status; mCurrentMediaStatus = status;
Q_EMIT mediaStatusChanged(mCurrentMediaStatus);
updateBufferStatus(); updateBufferStatus();
} }
......
...@@ -112,6 +112,7 @@ private: ...@@ -112,6 +112,7 @@ private:
int mPendingVolume; int mPendingVolume;
int mPendingMute; int mPendingMute;
QScopedPointer<QTemporaryFile> mTempFile; QScopedPointer<QTemporaryFile> mTempFile;
int mActiveStateChangeNotifiers;
void setState(QMediaPlayer::State state); void setState(QMediaPlayer::State state);
void setMediaStatus(QMediaPlayer::MediaStatus status); void setMediaStatus(QMediaPlayer::MediaStatus status);
...@@ -122,6 +123,8 @@ private: ...@@ -122,6 +123,8 @@ private:
void resetBufferingProgress(); void resetBufferingProgress();
void flushPendingStates(); void flushPendingStates();
void updateBufferStatus(); void updateBufferStatus();
friend class StateChangeNotifier;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment