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:
@@ -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)
|
|||||||
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)
|
|||||||
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
|
|||||||
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)
|
|||||||
|
|
||||||
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()
|
|||||||
|
|
||||||
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()
|
|||||||
|
|
||||||
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()
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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
|
|||||||
Q_EMIT durationChanged(duration());
|
Q_EMIT durationChanged(duration());
|
||||||
|
|
||||||
mCurrentMediaStatus = status;
|
mCurrentMediaStatus = status;
|
||||||
Q_EMIT mediaStatusChanged(mCurrentMediaStatus);
|
|
||||||
|
|
||||||
updateBufferStatus();
|
updateBufferStatus();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
|||||||
void resetBufferingProgress();
|
void resetBufferingProgress();
|
||||||
void flushPendingStates();
|
void flushPendingStates();
|
||||||
void updateBufferStatus();
|
void updateBufferStatus();
|
||||||
|
|
||||||
|
friend class StateChangeNotifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|||||||
Reference in New Issue
Block a user