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: Christian Stromme <christian.stromme@digia.com>
This commit is contained in:
Yoann Lopes
2014-09-16 17:30:27 +02:00
parent 49dc6dc459
commit c1c205b772
2 changed files with 53 additions and 3 deletions

View File

@@ -37,6 +37,36 @@
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)
: QMediaPlayerControl(parent),
mMediaPlayer(new AndroidMediaPlayer),
@@ -55,7 +85,8 @@ QAndroidMediaPlayerControl::QAndroidMediaPlayerControl(QObject *parent)
mPendingPosition(-1),
mPendingSetMedia(false),
mPendingVolume(-1),
mPendingMute(-1)
mPendingMute(-1),
mActiveStateChangeNotifiers(0)
{
connect(mMediaPlayer,SIGNAL(bufferingChanged(qint32)),
this,SLOT(onBufferingChanged(qint32)));
@@ -138,6 +169,8 @@ void QAndroidMediaPlayerControl::setPosition(qint64 position)
return;
}
StateChangeNotifier notifier(this);
if (mCurrentMediaStatus == QMediaPlayer::EndOfMedia)
setMediaStatus(QMediaPlayer::LoadedMedia);
@@ -275,6 +308,8 @@ const QIODevice *QAndroidMediaPlayerControl::mediaStream() const
void QAndroidMediaPlayerControl::setMedia(const QMediaContent &mediaContent,
QIODevice *stream)
{
StateChangeNotifier notifier(this);
const bool reloading = (mMediaContent == mediaContent);
if (!reloading) {
@@ -346,6 +381,8 @@ void QAndroidMediaPlayerControl::setVideoOutput(QObject *videoOutput)
void QAndroidMediaPlayerControl::play()
{
StateChangeNotifier notifier(this);
// We need to prepare the mediaplayer again.
if ((mState & AndroidMediaPlayer::Stopped) && !mMediaContent.isNull()) {
setMedia(mMediaContent, mMediaStream);
@@ -366,6 +403,8 @@ void QAndroidMediaPlayerControl::play()
void QAndroidMediaPlayerControl::pause()
{
StateChangeNotifier notifier(this);
setState(QMediaPlayer::PausedState);
if ((mState & (AndroidMediaPlayer::Started
@@ -380,6 +419,8 @@ void QAndroidMediaPlayerControl::pause()
void QAndroidMediaPlayerControl::stop()
{
StateChangeNotifier notifier(this);
setState(QMediaPlayer::StoppedState);
if ((mState & (AndroidMediaPlayer::Prepared
@@ -397,6 +438,8 @@ void QAndroidMediaPlayerControl::stop()
void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
{
StateChangeNotifier notifier(this);
Q_UNUSED(extra);
switch (what) {
case AndroidMediaPlayer::MEDIA_INFO_UNKNOWN:
@@ -428,6 +471,8 @@ void QAndroidMediaPlayerControl::onInfo(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
{
StateChangeNotifier notifier(this);
QString errorString;
QMediaPlayer::Error error = QMediaPlayer::ResourceError;
@@ -480,6 +525,8 @@ void QAndroidMediaPlayerControl::onError(qint32 what, qint32 extra)
void QAndroidMediaPlayerControl::onBufferingChanged(qint32 percent)
{
StateChangeNotifier notifier(this);
mBuffering = percent != 100;
mBufferPercent = percent;
@@ -511,6 +558,8 @@ void QAndroidMediaPlayerControl::onStateChanged(qint32 state)
return;
}
StateChangeNotifier notifier(this);
mState = state;
switch (mState) {
case AndroidMediaPlayer::Idle:
@@ -599,7 +648,6 @@ void QAndroidMediaPlayerControl::setState(QMediaPlayer::State state)
return;
mCurrentState = state;
Q_EMIT stateChanged(mCurrentState);
}
void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status)
@@ -614,7 +662,6 @@ void QAndroidMediaPlayerControl::setMediaStatus(QMediaPlayer::MediaStatus status
Q_EMIT durationChanged(duration());
mCurrentMediaStatus = status;
Q_EMIT mediaStatusChanged(mCurrentMediaStatus);
updateBufferStatus();
}

View File

@@ -112,6 +112,7 @@ private:
int mPendingVolume;
int mPendingMute;
QScopedPointer<QTemporaryFile> mTempFile;
int mActiveStateChangeNotifiers;
void setState(QMediaPlayer::State state);
void setMediaStatus(QMediaPlayer::MediaStatus status);
@@ -122,6 +123,8 @@ private:
void resetBufferingProgress();
void flushPendingStates();
void updateBufferStatus();
friend class StateChangeNotifier;
};
QT_END_NAMESPACE