/*
* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: Class for retrieving and selecting media renderers
*
*/
// INCLUDES
#include <mpxplaybackplugin.h>
#include <mpxplaybackpluginobserver.h>
#include "upnpavrenderingsession.h"
#include "upnpavdevice.h"
#include "upnpitemutility.h" // for UPnPDurationToMilliseconds
#include "upnpmusicplayer.h"
#include "upnptrack.h" // for TrackDuration
#include "upnpvaluestatemachine.h"
#include "upnppluginserrortranslation.h"
_LIT( KComponentLogfile, "musicplugins.txt");
#include "upnplog.h"
// CONSTANT
const TInt KDefaultMaxVolume = 100;
const TInt KDefaultMinVolume = 0;
// ======== MEMBER FUNCTIONS ========
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::NewL
// 1st phase constructor.
// --------------------------------------------------------------------------
//
CUPnPValueStateMachine* CUPnPValueStateMachine::NewL(
CUPnPMusicPlayer& aParent,
MUPnPAVRenderingSession& aRenderingSession )
{
__LOG( "ValueStateMachine: NewL" );
CUPnPValueStateMachine* self = new(ELeave)
CUPnPValueStateMachine( aParent, aRenderingSession );
return self;
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::CUPnPValueStateMachine
// Default constructor.
// --------------------------------------------------------------------------
//
CUPnPValueStateMachine::CUPnPValueStateMachine(
CUPnPMusicPlayer& aParent,
MUPnPAVRenderingSession& aRenderingSession ) :
iParent( aParent ),
iRendererSession( aRenderingSession ),
iCurrentOperation( EOperationNone ),
iRendererVolume( KErrNotFound ),
iRendererMuted( KErrNotFound )
{
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::~CUPnPValueStateMachine
// Destructor.
// --------------------------------------------------------------------------
//
CUPnPValueStateMachine::~CUPnPValueStateMachine()
{
__LOG( "ValueStateMachine: destructor" );
iOperationQueue.Close();
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::CopyValues
// copies renderer-specific cached values from another instance
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::CopyValues(
const CUPnPValueStateMachine& aOther )
{
iRendererVolume = aOther.iRendererVolume;
iRendererMuted = aOther.iRendererMuted;
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::ValidatePropertyInState
// defines the rules of getting / setting in different states
// --------------------------------------------------------------------------
//
CUPnPValueStateMachine::TValidationResult
CUPnPValueStateMachine::ValidatePropertyInState(
TMPXPlaybackProperty aProperty,
TBool aSetting,
TInt aPlayerState,
TBool aIsReady )
{
switch( aProperty )
{
case EPbPropertyMaxVolume: // fall through
case EPbPropertyRemote: // fall through
case EPbPropertySupportedFeatures:
{
// allow getting in all states,
// trying to set will result to error
if ( !aSetting )
{
return EHandleStatic;
}
else
{
return EErrorNotSupported;
}
}
case EPbPropertyVolume: // fall through
case EPbPropertyMute:
{
// allow volume get/set after initialisation when remote device
// is ready. In other states respond with error
if ( aPlayerState ==
CUPnPMusicPlayer::EStateActive )
{
if( !aIsReady )
{
return EErrorNotReady;
}
else
{
return EHandle;
}
}
else if ( aPlayerState ==
CUPnPMusicPlayer::EStatePreInitialized ||
aPlayerState ==
CUPnPMusicPlayer::EStateWaiting ||
aPlayerState ==
CUPnPMusicPlayer::EStateActiveForceInitialise )
{
return EHandle;
}
else
{
return EErrorNotReady;
}
}
case EPbPropertyDuration:
{
// duration setting is not allowed
// getting is allowed after initialised, but will result
// to returning plain zero in other states except active
// when it is actually asked from the device
if ( aSetting )
{
return EErrorNotSupported;
}
else if ( aPlayerState ==
CUPnPMusicPlayer::EStateActive )
{
if( aIsReady )
{
return EHandle;
}
else
{
// On active state but device is not ready ->
// Use initial values.
return EHandleStatic;
}
}
else if ( aPlayerState ==
CUPnPMusicPlayer::EStatePreInitialized ||
aPlayerState ==
CUPnPMusicPlayer::EStateWaiting ||
aPlayerState ==
CUPnPMusicPlayer::EStateActiveForceInitialise )
{
return EHandleStatic;
}
else
{
return EErrorNotReady;
}
}
case EPbPropertyPosition:
{
// position get/set is allowed after init when remote device
// is ready. Only active state it will result to real action
if ( aPlayerState ==
CUPnPMusicPlayer::EStateActive )
{
if( aIsReady )
{
return EHandle;
}
else
{
// On active state but device is not ready ->
// Use initial values.
return EHandleStatic;
}
}
else if ( aPlayerState ==
CUPnPMusicPlayer::EStatePreInitialized ||
aPlayerState ==
CUPnPMusicPlayer::EStateWaiting ||
aPlayerState ==
CUPnPMusicPlayer::EStateActiveForceInitialise )
{
return EHandleStatic;
}
else
{
return EErrorNotReady;
}
}
default:
{
// unsupported property
return EErrorNotSupported;
}
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::SetL
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::SetL( TMPXPlaybackProperty aProperty,
TInt aValue )
{
// Check if volume or mute is supported by device
if( ( aProperty == EPbPropertyVolume &&
!iParent.UsedRendererDevice().VolumeCapability() ) ||
( aProperty == EPbPropertyMute &&
!iParent.UsedRendererDevice().MuteCapability() )
)
{
__LOG( "ValueStateMachine::SetL - \
Request is not supported by device" );
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPSetComplete,
(TInt)aProperty, KErrNotSupported );
return;
}
// Check from queue if alredy requested.
if( FoundFromQueue( aProperty ) )
{
__LOG( "ValueStateMachine::SetL: Volume query Ignored!" );
// Ignore
return;
}
if ( !iCurrentOperation.None() )
{
__LOG( "ValueStateMachine::SetL - Append to queue" );
iOperationQueue.AppendL( TOperation( aProperty, aValue ) );
return;
}
switch( aProperty )
{
case EPbPropertyVolume:
{
__LOG1( "ValueStateMachine: SetVolume(%d)",
aValue );
// Set the volume, do a sanity check
if( aValue < KDefaultMinVolume || aValue > KDefaultMaxVolume )
{
// Given value out of range
CheckOperationInQueueL();
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPSetComplete,
aProperty, KErrArgument );
}
else if ( aValue == iRendererVolume )
{
// re-setting the same volume
if ( iRendererMuted )
{
MuteRequestL( 0 );
}
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPSetComplete,
aProperty, KErrNone );
}
else
{
iCurrentOperation.Set( aProperty, aValue );
iRendererSession.SetVolumeL( aValue );
if ( iRendererMuted )
{
// unmute after volume has been adjusted
MuteRequestL( 0 );
}
}
break;
}
case EPbPropertyMute:
{
__LOG1( "ValueStateMachine: SetMute(%d)",
aValue );
if( aValue != 0 && iRendererMuted != 1 )
{
// set mute on
iCurrentOperation.Set( aProperty, 1 );
iRendererSession.SetMuteL( ETrue );
}
else if ( aValue == 0 && iRendererMuted != 0 )
{
// set mute off
iCurrentOperation.Set( aProperty, 0 );
iRendererSession.SetMuteL( EFalse );
}
else
{
// mute is already in requested state
CheckOperationInQueueL();
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPSetComplete,
aProperty, KErrNone );
}
break;
}
default: // Given property is not supported
{
__LOG( "ValueStateMachine: Set - default" );
CheckOperationInQueueL();
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPSetComplete,
aProperty, KErrNotSupported );
break;
}
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::ValueL
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::ValueL( TMPXPlaybackProperty aProperty )
{
// Check if volume or mute is supported by device
if( ( aProperty == EPbPropertyVolume &&
!iParent.UsedRendererDevice().VolumeCapability() ) ||
( aProperty == EPbPropertyMute &&
!iParent.UsedRendererDevice().MuteCapability() )
)
{
__LOG( "ValueStateMachine::ValueL - \
Request is not supported by device" );
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPSetComplete,
(TInt)aProperty, KErrNotSupported );
return;
}
if ( !iCurrentOperation.None() )
{
__LOG( "ValueStateMachine::ValueL - Append to queue" );
iOperationQueue.AppendL( TOperation( aProperty ) );
return;
}
switch( aProperty )
{
case EPbPropertyVolume:
{
__LOG( "ValueStateMachine: Value(volume)" );
iRendererSession.GetVolumeL();
iCurrentOperation.Set( aProperty );
break;
}
case EPbPropertyMute:
{
__LOG( "ValueStateMachine: Value(mute)" );
iRendererSession.GetMuteL();
iCurrentOperation.Set( aProperty );
break;
}
case EPbPropertyDuration:
{
__LOG( "ValueStateMachine: Value(duration)" );
if ( iParent.Track().TrackDuration() > 0 )
{
// duration found in cache
CheckOperationInQueueL();
iParent.Observer().HandleProperty( aProperty,
iParent.Track().TrackDuration(), KErrNone );
}
else
{
iRendererSession.GetPositionInfoL();
iCurrentOperation.Set( aProperty );
}
break;
}
case EPbPropertyPosition:
{
__LOG( "ValueStateMachine: Value(position)" );
iRendererSession.GetPositionInfoL();
iCurrentOperation.Set( aProperty );
break;
}
default:
{
__PANICD( __FILE__, __LINE__ );
break;
}
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::ValueStatic
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::ValueStatic(
TMPXPlaybackProperty aProperty,
MMPXPlaybackPluginObserver& aPlaybackObs )
{
switch( aProperty )
{
case EPbPropertyMaxVolume:
{
__LOG( "ValueStateMachine: ValueStatic(max volume)" );
aPlaybackObs.HandleProperty( aProperty,
KDefaultMaxVolume, KErrNone );
break;
}
case EPbPropertyRemote:
{
__LOG( "ValueStateMachine: ValueStatic(remote)" );
aPlaybackObs.HandleProperty( aProperty,
(TInt)EFalse, KErrNone );
break;
}
case EPbPropertySupportedFeatures:
{
__LOG( "ValueStateMachine: ValueStatic(features)" );
// No support for any features
TInt supportedFeatures = 0;
aPlaybackObs.HandleProperty( aProperty,
supportedFeatures, KErrNone );
break;
}
case EPbPropertyDuration:
{
__LOG( "ValueStateMachine: ValueStatic(duration)" );
TInt initialDuration = 0;
aPlaybackObs.HandleProperty( aProperty,
initialDuration, KErrNone );
break;
}
case EPbPropertyPosition:
{
__LOG( "ValueStateMachine: ValueStatic(position)" );
TInt initialPosition = 1;
aPlaybackObs.HandleProperty( aProperty,
initialPosition, KErrNone );
break;
}
default:
{
__PANICD( __FILE__, __LINE__ );
break;
}
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::DurationQueryL
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::DurationQueryL()
{
// here we could check if the duration is already present in
// iParent.track() however it was decided that we check the duration
// from renderer anyway and trust the renderer's duration more.
if ( !iCurrentOperation.None() )
{
__LOG( "ValueStateMachine::DurationQueryL - Append to queue" );
iOperationQueue.AppendL( EOperationDurationQuery );
return;
}
__LOG( "ValueStateMachine::DurationQueryL" );
iRendererSession.GetPositionInfoL();
iCurrentOperation = EOperationDurationQuery;
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::PositionQueryL
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::PositionQueryL()
{
__LOG( "ValueStateMachine::PositionQueryL" );
if ( !iCurrentOperation.None() )
{
__LOG( "ValueStateMachine::PositionQueryL - Append to queue" );
iOperationQueue.AppendL( EOperationPositionQuery );
return;
}
iRendererSession.GetPositionInfoL();
iCurrentOperation = EOperationPositionQuery;
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::VolumeQueryL
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::VolumeQueryL()
{
// Check if volume feature is supported by device.
if( iParent.UsedRendererDevice().VolumeCapability() )
{
if ( iRendererVolume != KErrNotFound )
{
// Volume query not required - already cached.
return;
}
if ( !iCurrentOperation.None() )
{
__LOG( "ValueStateMachine::VolumeQueryL - Append to queue" );
iOperationQueue.AppendL( EOperationVolumeQuery );
return;
}
__LOG( "ValueStateMachine::VolumeQueryL" );
iRendererSession.GetVolumeL();
iCurrentOperation = EOperationVolumeQuery;
}
else
{
// Get volume is not supported. Do nothing.
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::MuteRequestL
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::MuteRequestL( TInt aMute )
{
if ( !iCurrentOperation.None() )
{
__LOG( "ValueStateMachine::MuteRequestL - Append to queue" );
iOperationQueue.AppendL( TOperation( EOperationMute, aMute ) );
return;
}
__LOG1( "ValueStateMachine: MuteRequest(%d)", aMute );
if( aMute != 0 && iRendererMuted != 1 )
{
// set mute on
iCurrentOperation = EOperationMute;
iRendererSession.SetMuteL( ETrue );
}
else if ( aMute == 0 && iRendererMuted != 0 )
{
// set mute off
iCurrentOperation = EOperationMute;
iRendererSession.SetMuteL( EFalse );
}
else
{
// mute is already in requested state
CheckOperationInQueueL();
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::VolumeResult
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::VolumeResult( TInt aError, TInt aVolumeLevel,
TBool aActionResponse )
{
aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
// If response for get volume
if( aActionResponse )
{
if (aError == KErrNone)
{
iRendererVolume = aVolumeLevel;
}
if( iCurrentOperation.Compare( EOperationValue, EPbPropertyVolume ) )
{
__LOG( "ValueStateMachine::VolumeResult: Value resp." );
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
iParent.Observer().HandleProperty( EPbPropertyVolume,
iRendererVolume, aError );
}
else if( iCurrentOperation.Compare( EOperationSet,
EPbPropertyVolume ) )
{
__LOG( "ValueStateMachine::VolumeResult: Set resp." );
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPSetComplete,
(TInt)EPbPropertyVolume, aError );
}
else if ( iCurrentOperation == EOperationVolumeQuery )
{
__LOG1("VolumeQueryResult: Volume query resp err=%d", aError );
if ( aError == KErrNone )
{
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPVolumeChanged,
iRendererVolume, aError );
}
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
}
else
{
iCurrentOperation.Reset();
__LOG( "ValueStateMachine::VolumeResult: no request?" );
}
}
else // Volume changed from device
{
// Ignore volume events from device if volume control
// is ongoing on handset.
if( iCurrentOperation.Compare( EOperationSet, EPbPropertyVolume ) )
{
return;
}
if (aError == KErrNone)
{
iRendererVolume = aVolumeLevel;
}
if ( !iRendererMuted )
{
__LOG1( "ValueStateMachine::VolumeResult: from device: (%d)",
aVolumeLevel );
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPVolumeChanged,
iRendererVolume, aError );
}
else
{
__LOG( "ValueStateMachine::VolumeResult: from device (muted)" );
}
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::MuteResult
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::MuteResult( TInt aError, TBool aMute,
TBool aActionResponse )
{
aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
// Response for set mute
if( aActionResponse )
{
if( iCurrentOperation.Compare( EOperationValue, EPbPropertyMute ) )
{
__LOG( "ValueStateMachine::MuteResult: Value resp." );
iRendererMuted = aMute;
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
iParent.Observer().HandleProperty( EPbPropertyMute,
(TInt)aMute, aError );
}
else if ( iCurrentOperation.Compare( EOperationSet,
EPbPropertyMute ) )
{
__LOG( "ValueStateMachine::MuteResult: Set resp." );
iRendererMuted = aMute;
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPSetComplete,
(TInt)EPbPropertyMute, aError );
}
else if ( iCurrentOperation == EOperationMute )
{
// internal operation, no event.
iRendererMuted = aMute;
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
}
else
{
iRendererMuted = aMute;
iCurrentOperation.Reset();
__LOG( "ValueStateMachine::MuteResult: no request?" );
}
}
else // Mute changed from device
{
__LOG( "ValueStateMachine::MuteResult: Mute changed from device" );
if( aMute )
{
iRendererMuted = ETrue;
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPVolumeChanged,
0, aError );
}
else
{
iRendererMuted = EFalse;
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPVolumeChanged,
iRendererVolume, aError );
}
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::PositionInfoResult
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::PositionInfoResult( TInt aStatus,
const TDesC8& aTrackPosition, const TDesC8& aTrackLength )
{
// Check if position info was asked
if( iCurrentOperation.Compare( EOperationValue, EPbPropertyPosition ) )
{
__LOG1( "Position response err=%d", aStatus );
TInt ms = 0;
if( aStatus == KErrNone )
{
// Convert the descriptor to integer value
aStatus = UPnPItemUtility::UPnPDurationAsMilliseconds(
aTrackPosition, ms );
__LOG2( "ValueStateMachine::PositionInfoResult position=%d err=%d",
ms, aStatus );
}
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
// Use initial position value in case of errors or position 0.
// This will guarantee that in case of unpause, SetPosition
// is called with real value even if remote player does not
// return real value for getposition call. Note that
// SetPosition(0) is used when user really wants to move to
// track beginning.
if( aStatus != KErrNone )
{
// GetPositionInfo is not supported by used device.
iParent.Observer().HandleProperty( EPbPropertyPosition, 1,
KErrNotSupported );
}
else
{
if( ms == 0 )
{
ms = 1;
}
iParent.Observer().HandleProperty( EPbPropertyPosition, ms,
aStatus );
}
}
else if ( iCurrentOperation == EOperationPositionQuery )
{
__LOG1( "PositionQuery response err=%d", aStatus );
TInt ms = 0;
if( aStatus == KErrNone )
{
// Convert the descriptor to integer value
aStatus = UPnPItemUtility::UPnPDurationAsMilliseconds(
aTrackPosition, ms );
__LOG2( "ValueStateMachine::PositionInfoResult position=%d err=%d",
ms, aStatus );
}
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
if( aStatus == KErrNone )
{
if( ms == 0 )
{
ms = 1;
}
//iParent.Observer().HandlePluginEvent(
//MMPXPlaybackPluginObserver::EPPositionChanged, ms, KErrNone );
}
}
// Check if duration info was asked
else if( iCurrentOperation.Compare( EOperationValue,
EPbPropertyDuration ) )
{
__LOG1( "Duration response err=%d", aStatus );
TInt ms = 0;
if( aStatus == KErrNone )
{
aStatus = UPnPItemUtility::UPnPDurationAsMilliseconds(
aTrackLength, ms );
__LOG2( "ValueStateMachine::PositionInfoResult -\
duration=%d err=%d", ms, aStatus );
if ( aStatus == KErrNone )
{
iParent.Track().SetTrackDuration( ms );
}
}
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
if( aStatus == KErrNotSupported )
{
// GetDuration is not supported by used device.
// Use initial duration value (1). It will guarantee that in
// case of unpause, SetPosition is called with real value even
// if remote player does not return real value for getposition
// call. Note that SetPosition(0) is used when user really wants
// to move to track beginning.
iParent.Observer().HandleProperty( EPbPropertyDuration, 1,
KErrNone );
}
else
{
iParent.Observer().HandleProperty( EPbPropertyDuration,
ms, aStatus );
}
}
else if ( iCurrentOperation == EOperationDurationQuery )
{
__LOG1( "DurationQuery response err=%d", aStatus );
TInt ms = 0;
if( aStatus == KErrNone )
{
aStatus = UPnPItemUtility::UPnPDurationAsMilliseconds(
aTrackLength, ms );
__LOG2( "ValueStateMachine::PositionInfoResult - \
duration=%d err=%d",
ms, aStatus );
if ( aStatus == KErrNone )
{
iParent.Track().SetTrackDuration( ms );
}
}
iCurrentOperation.Reset();
TRAP_IGNORE( CheckOperationInQueueL() );
if ( iParent.Track().TrackDuration() > 0 && aStatus == KErrNone )
{
iParent.Observer().HandlePluginEvent(
MMPXPlaybackPluginObserver::EPDurationChanged,
iParent.Track().TrackDuration(), KErrNone );
}
}
else
{
__LOG( "ValueStateMachine::PositionInfoResult: no request?" );
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::Cancel
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::Cancel()
{
// reset current operation and empty the queue -> no callbacks.
iCurrentOperation.Reset();
iOperationQueue.Reset();
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::CheckOperationInQueueL
// Checks if operations are in the queue, and executes
// --------------------------------------------------------------------------
//
void CUPnPValueStateMachine::CheckOperationInQueueL()
{
if ( !iCurrentOperation.None() )
{
// check operation though a current operation exists!
__PANICD( __FILE__, __LINE__ );
return;
}
if ( iOperationQueue.Count() > 0 )
{
TOperation op = iOperationQueue[0];
iOperationQueue.Remove(0);
if ( op == EOperationValue )
{
ValueL( op.iProperty );
}
else if ( op == EOperationSet )
{
SetL( op.iProperty, op.iValue );
}
else if ( op == EOperationDurationQuery )
{
DurationQueryL();
}
else if ( op == EOperationVolumeQuery )
{
VolumeQueryL();
}
else if ( op == EOperationPositionQuery )
{
PositionQueryL();
}
else if ( op == EOperationMute )
{
MuteRequestL( op.iValue );
}
else
{
__PANICD( __FILE__, __LINE__ );
}
}
}
// --------------------------------------------------------------------------
// CUPnPValueStateMachine::FoundFromQueue
// Checks if operations are in the queue
// --------------------------------------------------------------------------
//
TBool CUPnPValueStateMachine::FoundFromQueue(TMPXPlaybackProperty aProperty)
{
TBool found = EFalse;
TInt count = iOperationQueue.Count();
for( TInt i = 0; i < count; i++ )
{
TOperation op = iOperationQueue[i];
if( op.iProperty == aProperty )
{
found = ETrue;
break;
}
}
return found;
}