From c1c205b772c2ca0adb7b00fe02d27a59429dd068 Mon Sep 17 00:00:00 2001 From: Yoann Lopes Date: Tue, 16 Sep 2014 17:30:27 +0200 Subject: 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 --- .../src/mediaplayer/qandroidmediaplayercontrol.cpp | 53 ++++++++++++++++++++-- .../src/mediaplayer/qandroidmediaplayercontrol.h | 3 ++ 2 files changed, 53 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp index bd936f86d..fb1c8b72f 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.cpp @@ -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(); } diff --git a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h index ec4dd3280..7de0c2dcf 100644 --- a/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h +++ b/src/plugins/android/src/mediaplayer/qandroidmediaplayercontrol.h @@ -112,6 +112,7 @@ private: int mPendingVolume; int mPendingMute; QScopedPointer 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 -- cgit v1.2.3