From 3338d1b2fd7be7ce4633084e1fe8dd05de8cb70f Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 2 Dec 2009 11:39:44 +0000 Subject: Added error strings to Phonon MMF backend Note that changing Utils from a namespace into a class, and then using Q_DECLARE_TR_FUNCTIONS in the class declaration, was necessary in order to be able to call tr(...) from the implementation of Utils::symbianErrorToString. Task-number: QTBUG-4994 Reviewed-by: Oswald Buddenhagen (cherry picked from commit 3ed427637dd76da371174e14b0f7f2a15801fcac) --- src/3rdparty/phonon/mmf/abstractmediaplayer.cpp | 26 ++++--- src/3rdparty/phonon/mmf/abstractplayer.cpp | 12 ++- src/3rdparty/phonon/mmf/abstractplayer.h | 16 +++- src/3rdparty/phonon/mmf/audioplayer.cpp | 13 ++-- src/3rdparty/phonon/mmf/mediaobject.cpp | 12 +-- src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 22 +++--- src/3rdparty/phonon/mmf/utils.cpp | 98 +++++++++++++++++++++++++ src/3rdparty/phonon/mmf/utils.h | 22 ++++-- 8 files changed, 170 insertions(+), 51 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp index 99e96cd..bc38513 100644 --- a/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractmediaplayer.cpp @@ -70,7 +70,7 @@ void MMF::AbstractMediaPlayer::play() switch (privateState()) { case GroundState: - setError(NormalError); + setError(tr("Not ready to play")); break; case LoadingState: @@ -226,10 +226,13 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f m_source = source; TInt symbianErr = KErrNone; + QString errorMessage; switch (m_source.type()) { case MediaSource::LocalFile: { symbianErr = openFile(file); + if (KErrNone != symbianErr) + errorMessage = tr("Error opening file"); break; } @@ -238,11 +241,12 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f if (url.scheme() == QLatin1String("file")) { symbianErr = openFile(file); + if (KErrNone != symbianErr) + errorMessage = tr("Error opening URL"); } else { - TRACE_0("Source type not supported"); - // TODO: support network URLs - symbianErr = KErrNotSupported; + TRACE_0("Error opening URL: protocol not supported"); + errorMessage = tr("Error opening URL: protocol not supported"); } break; @@ -251,8 +255,8 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f case MediaSource::Invalid: case MediaSource::Disc: case MediaSource::Stream: - TRACE_0("Source type not supported"); - symbianErr = KErrNotSupported; + TRACE_0("Error opening source: type not supported"); + errorMessage = tr("Error opening source: type not supported"); break; case MediaSource::Empty: @@ -265,11 +269,13 @@ void MMF::AbstractMediaPlayer::setFileSource(const MediaSource &source, RFile& f TRACE_PANIC(InvalidMediaTypePanic); } - if (KErrNone == symbianErr) { + if (errorMessage.isEmpty()) { changeState(LoadingState); } else { - TRACE("error %d", symbianErr) - setError(NormalError); + if (symbianErr) + setError(errorMessage, symbianErr); + else + setError(errorMessage); } TRACE_EXIT_0(); @@ -318,7 +324,7 @@ void MMF::AbstractMediaPlayer::doVolumeChanged() const int err = setDeviceVolume(volume); if (KErrNone != err) { - setError(NormalError); + setError(tr("Setting volume failed"), err); } break; } diff --git a/src/3rdparty/phonon/mmf/abstractplayer.cpp b/src/3rdparty/phonon/mmf/abstractplayer.cpp index caf4092..13ff5fb 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.cpp +++ b/src/3rdparty/phonon/mmf/abstractplayer.cpp @@ -113,19 +113,23 @@ void MMF::AbstractPlayer::videoOutputChanged() // Default behaviour is empty - overridden by VideoPlayer } -void MMF::AbstractPlayer::setError(Phonon::ErrorType error, - const QString &errorMessage) +void MMF::AbstractPlayer::setError(const QString &errorMessage) { TRACE_CONTEXT(AbstractPlayer::setError, EAudioInternal); - TRACE_ENTRY("state %d error %d", m_state, error); + TRACE_ENTRY("state %d", m_state); - m_error = error; + m_error = Phonon::NormalError; m_errorString = errorMessage; changeState(ErrorState); TRACE_EXIT_0(); } +void MMF::AbstractPlayer::setError(const QString &errorMessage, int symbianError) +{ + setError(errorMessage + ": " + Utils::symbianErrorToString(symbianError)); +} + Phonon::ErrorType MMF::AbstractPlayer::errorType() const { const Phonon::ErrorType result = (ErrorState == m_state) diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index 2e9cfa0..9af1362 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -87,10 +87,20 @@ public: void setVideoOutput(VideoOutput* videoOutput); /** - * Records error and changes state to ErrorState + * Records error message and changes state to ErrorState */ - void setError(Phonon::ErrorType error, - const QString &errorMessage = QString()); + void setError(const QString &errorMessage); + + /** + * Records error message and changes state to ErrorState + * + * Appends a human-readable version of symbianErrorCode to the error message, + * e.g. + * setError(NormalError, "Opening file failed", KErrPermissionDenied) + * results in the following error message: + * "Opening file failed: permission denied" + */ + void setError(const QString &errorMessage, int symbianErrorCode); Phonon::State state() const; diff --git a/src/3rdparty/phonon/mmf/audioplayer.cpp b/src/3rdparty/phonon/mmf/audioplayer.cpp index 8fccfe6..72d6684 100644 --- a/src/3rdparty/phonon/mmf/audioplayer.cpp +++ b/src/3rdparty/phonon/mmf/audioplayer.cpp @@ -51,9 +51,8 @@ void MMF::AudioPlayer::construct() TRACE_ENTRY_0(); TRAPD(err, m_player.reset(CPlayerType::NewL(*this, 0, EMdaPriorityPreferenceNone))); - if (KErrNone != err) { - changeState(ErrorState); - } + if (KErrNone != err) + setError("Creation of audio player failed", err); TRACE_EXIT_0(); } @@ -151,7 +150,7 @@ qint64 MMF::AudioPlayer::currentTime() const // If we don't cast away constness here, we simply have to ignore // the error. - const_cast(this)->setError(NormalError); + const_cast(this)->setError(tr("Getting position failed"), err); } return result; @@ -186,8 +185,7 @@ void MMF::AudioPlayer::MapcInitComplete(TInt aError, updateMetaData(); changeState(StoppedState); } else { - // TODO: set different error states according to value of aError? - setError(NormalError); + setError(tr("Opening clip failed"), aError); } TRACE_EXIT_0(); @@ -208,8 +206,7 @@ void MMF::AudioPlayer::MapcPlayComplete(TInt aError) changeState(StoppedState); // TODO: move on to m_nextSource } else { - // TODO: do something with aError? - setError(NormalError); + setError(tr("Playback complete"), aError); } /* diff --git a/src/3rdparty/phonon/mmf/mediaobject.cpp b/src/3rdparty/phonon/mmf/mediaobject.cpp index 21dcfe1..6158ca1 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.cpp +++ b/src/3rdparty/phonon/mmf/mediaobject.cpp @@ -238,7 +238,6 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) const bool oldPlayerHasVideo = oldPlayer->hasVideo(); const bool oldPlayerSeekable = oldPlayer->isSeekable(); - Phonon::ErrorType error = NoError; QString errorMessage; // Determine media type @@ -255,7 +254,6 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) } else { errorMessage = QLatin1String("Network streaming not supported yet"); - error = NormalError; } } break; @@ -263,8 +261,7 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) case MediaSource::Invalid: case MediaSource::Disc: case MediaSource::Stream: - TRACE_0("Unsupported media type"); - error = NormalError; + errorMessage = tr("Error opening source: type not supported"); break; case MediaSource::Empty: @@ -287,8 +284,7 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) newPlayer = new DummyPlayer(); } - error = NormalError; - errorMessage = tr("Media type could not be determined"); + errorMessage = tr("Error opening source: media type could not be determined"); break; case MediaTypeAudio: @@ -326,9 +322,9 @@ void MMF::MediaObject::createPlayer(const MediaSource &source) // We need to call setError() after doing the connects, otherwise the // error won't be received. - if (error != NoError) { + if (!errorMessage.isEmpty()) { Q_ASSERT(m_player); - m_player->setError(error, errorMessage); + m_player->setError(errorMessage); } TRACE_EXIT_0(); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index b6f53ae..4619f54 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -93,7 +93,7 @@ void MMF::VideoPlayer::construct() m_dsaActive = true; if (KErrNone != err) - changeState(ErrorState); + setError("Creation of video player failed", err); TRACE_EXIT_0(); } @@ -129,7 +129,7 @@ void MMF::VideoPlayer::doPause() TRAPD(err, m_player->PauseL()); if (KErrNone != err) { TRACE("PauseL error %d", err); - setError(NormalError); + setError(tr("Pause failed"), err); } } @@ -158,7 +158,7 @@ void MMF::VideoPlayer::doSeek(qint64 ms) } else { TRACE("SetPositionL error %d", err); - setError(NormalError); + setError(tr("Seek failed"), err); } } @@ -200,7 +200,7 @@ qint64 MMF::VideoPlayer::currentTime() const // If we don't cast away constness here, we simply have to ignore // the error. - const_cast(this)->setError(NormalError); + const_cast(this)->setError(tr("Getting position failed"), err); } return result; @@ -226,7 +226,7 @@ void MMF::VideoPlayer::MvpuoOpenComplete(TInt aError) if (KErrNone == aError) m_player->Prepare(); else - setError(NormalError); + setError(tr("Opening clip failed"), aError); TRACE_EXIT_0(); } @@ -252,7 +252,7 @@ void MMF::VideoPlayer::MvpuoPrepareComplete(TInt aError) emit totalTimeChanged(totalTime()); changeState(StoppedState); } else { - setError(NormalError); + setError(tr("Buffering clip failed"), err); } TRACE_EXIT_0(); @@ -412,7 +412,7 @@ void MMF::VideoPlayer::startDirectScreenAccess() if(KErrNone == err) m_dsaActive = true; else - setError(NormalError); + setError(tr("Video display error"), err); } } @@ -424,7 +424,7 @@ bool MMF::VideoPlayer::stopDirectScreenAccess() if(KErrNone == err) m_dsaActive = false; else - setError(NormalError); + setError(tr("Video display error"), err); } return dsaWasActive; } @@ -600,7 +600,7 @@ void MMF::VideoPlayer::applyVideoWindowChange() TRAPD(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (1) err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } if(KErrNone == err) { @@ -615,13 +615,13 @@ void MMF::VideoPlayer::applyVideoWindowChange() if (KErrNone != err) { TRACE("SetDisplayWindowL err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } else { m_dsaActive = true; TRAP(err, m_player->SetScaleFactorL(m_scaleWidth, m_scaleHeight, antialias)); if(KErrNone != err) { TRACE("SetScaleFactorL (2) err %d", err); - setError(NormalError); + setError(tr("Video display error"), err); } } } diff --git a/src/3rdparty/phonon/mmf/utils.cpp b/src/3rdparty/phonon/mmf/utils.cpp index d728fcf..75fec9f 100644 --- a/src/3rdparty/phonon/mmf/utils.cpp +++ b/src/3rdparty/phonon/mmf/utils.cpp @@ -18,6 +18,7 @@ along with this library. If not, see . #include "utils.h" #include +#include QT_BEGIN_NAMESPACE @@ -69,6 +70,103 @@ MMF::MediaType MMF::Utils::mimeTypeToMediaType(const TDesC& mimeType) return result; } +QString MMF::Utils::symbianErrorToString(int errorCode) +{ + /** + * Here we translate only the error codes which are likely to be + * meaningful to the user. For example, when an error occurs + * during opening of a media file, displaying "not found" or + * "permission denied" is informative. On the other hand, + * differentiating between KErrGeneral and KErrArgument at the UI + * level does not make sense. + */ + switch (errorCode) + { + // System-wide errors + case KErrNone: + return tr("no error"); + case KErrNotFound: + return tr("not found"); + case KErrNoMemory: + return tr("out of memory"); + case KErrNotSupported: + return tr("not supported"); + case KErrOverflow: + return tr("overflow"); + case KErrUnderflow: + return tr("underflow"); + case KErrAlreadyExists: + return tr("already exists"); + case KErrPathNotFound: + return tr("path not found"); + case KErrInUse: + return tr("in use"); + case KErrNotReady: + return tr("not ready"); + case KErrAccessDenied: + return tr("access denied"); + case KErrCouldNotConnect: + return tr("could not connect"); + case KErrDisconnected: + return tr("disconnected"); + case KErrPermissionDenied: + return tr("permission denied"); + + // Multimedia framework errors + case KErrMMNotEnoughBandwidth: + return tr("insufficient bandwidth"); + case KErrMMSocketServiceNotFound: + case KErrMMServerSocket: + return tr("network unavailable"); + case KErrMMNetworkRead: + case KErrMMNetworkWrite: + case KErrMMUDPReceive: + return tr("network communication error"); + case KErrMMServerNotSupported: + return tr("streaming not supported"); + case KErrMMServerAlert: + return tr("server alert"); + case KErrMMInvalidProtocol: + return tr("invalid protocol"); + case KErrMMInvalidURL: + return tr("invalid URL"); + case KErrMMMulticast: + return tr("multicast error"); + case KErrMMProxyServer: + case KErrMMProxyServerConnect: + return tr("proxy server error"); + case KErrMMProxyServerNotSupported: + return tr("proxy server not supported"); + case KErrMMAudioDevice: + return tr("audio output error"); + case KErrMMVideoDevice: + return tr("video output error"); + case KErrMMDecoder: + return tr("decoder error"); + case KErrMMPartialPlayback: + return tr("audio or video components could not be played"); + case KErrMMDRMNotAuthorized: + return tr("DRM error"); + + /* + // We don't use QoS settings + case KErrMMQosLowBandwidth: + case KErrMMQosUnsupportedTrafficClass: + case KErrMMQosPoorTrafficClass: + case KErrMMQosUnsupportedParameters: + case KErrMMQosPoorParameters: + case KErrMMQosNotSupported: + */ + + // Catch-all for errors other than those above + default: + { + QString errorString; + errorString.setNum(errorCode); + return tr("unknown error") + " (" + errorString + ")"; + } + } +} #ifndef QT_NO_DEBUG diff --git a/src/3rdparty/phonon/mmf/utils.h b/src/3rdparty/phonon/mmf/utils.h index 7e363e8..60c03a5 100644 --- a/src/3rdparty/phonon/mmf/utils.h +++ b/src/3rdparty/phonon/mmf/utils.h @@ -21,7 +21,7 @@ along with this library. If not, see . #include #include // for RDebug - +#include // for Q_DECLARE_TR_FUNCTIONS #include #include "defs.h" @@ -41,32 +41,40 @@ enum PanicCode { InvalidBackendInterfaceClass = 3 }; -namespace Utils +class Utils { + Q_DECLARE_TR_FUNCTIONS(Utils) + +public: /** * Raise a fatal exception */ -void panic(PanicCode code); +static void panic(PanicCode code); /** * Determines whether the provided MIME type is an audio or video * type. If it is neither, the function returns MediaTypeUnknown. */ -MediaType mimeTypeToMediaType(const TDesC& mimeType); +static MediaType mimeTypeToMediaType(const TDesC& mimeType); + +/** + * Translates a Symbian error code into a user-readable string. + */ +static QString symbianErrorToString(int errorCode); #ifndef QT_NO_DEBUG /** * Retrieve color of specified pixel from the screen. */ -QColor getScreenPixel(const QPoint& pos); +static QColor getScreenPixel(const QPoint& pos); /** * Samples a small number of pixels from the screen, and dumps their * colors to the debug log. */ -void dumpScreenPixelSample(); +static void dumpScreenPixelSample(); #endif -} +}; /** * Available trace categories; -- cgit v0.12