upnpmpxplugins/upnpplaybackplugins/src/upnpvaluestatemachine.cpp
branchIOP_Improvements
changeset 40 08b5eae9f9ff
parent 39 6369bfd1b60d
child 41 b4d83ea1d6e2
equal deleted inserted replaced
39:6369bfd1b60d 40:08b5eae9f9ff
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:      Class for retrieving and selecting media renderers
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 // INCLUDES
       
    24 #include <mpxplaybackplugin.h>
       
    25 #include <mpxplaybackpluginobserver.h>
       
    26 #include "upnpavrenderingsession.h"
       
    27 #include "upnpavdevice.h"
       
    28 #include "upnpitemutility.h" // for UPnPDurationToMilliseconds
       
    29 #include "upnpmusicplayer.h"
       
    30 #include "upnptrack.h" // for TrackDuration
       
    31 #include "upnpvaluestatemachine.h"
       
    32 #include "upnppluginserrortranslation.h"
       
    33 
       
    34 _LIT( KComponentLogfile, "musicplugins.txt");
       
    35 #include "upnplog.h"
       
    36 
       
    37 // CONSTANT
       
    38 const TInt KDefaultMaxVolume = 100;
       
    39 const TInt KDefaultMinVolume = 0;
       
    40 
       
    41 // ======== MEMBER FUNCTIONS ========
       
    42 
       
    43 // --------------------------------------------------------------------------
       
    44 // CUPnPValueStateMachine::NewL
       
    45 // 1st phase constructor.
       
    46 // --------------------------------------------------------------------------
       
    47 //
       
    48 CUPnPValueStateMachine* CUPnPValueStateMachine::NewL(
       
    49     CUPnPMusicPlayer& aParent,
       
    50     MUPnPAVRenderingSession& aRenderingSession )
       
    51     {
       
    52     __LOG( "ValueStateMachine: NewL" );
       
    53     CUPnPValueStateMachine* self = new(ELeave)
       
    54         CUPnPValueStateMachine( aParent, aRenderingSession );
       
    55     return self;
       
    56     }
       
    57 
       
    58 // --------------------------------------------------------------------------
       
    59 // CUPnPValueStateMachine::CUPnPValueStateMachine
       
    60 // Default constructor.
       
    61 // --------------------------------------------------------------------------
       
    62 // 
       
    63 CUPnPValueStateMachine::CUPnPValueStateMachine( 
       
    64     CUPnPMusicPlayer& aParent,
       
    65     MUPnPAVRenderingSession& aRenderingSession ) :
       
    66         iParent( aParent ),
       
    67         iRendererSession( aRenderingSession ),
       
    68         iCurrentOperation( EOperationNone ),
       
    69         iRendererVolume( KErrNotFound ),
       
    70         iRendererMuted( KErrNotFound )
       
    71     {
       
    72     }
       
    73 
       
    74 
       
    75 // --------------------------------------------------------------------------
       
    76 // CUPnPValueStateMachine::~CUPnPValueStateMachine
       
    77 // Destructor.
       
    78 // --------------------------------------------------------------------------
       
    79 //
       
    80 CUPnPValueStateMachine::~CUPnPValueStateMachine()
       
    81     {
       
    82     __LOG( "ValueStateMachine: destructor" );
       
    83     iOperationQueue.Close();
       
    84     }
       
    85 
       
    86 // --------------------------------------------------------------------------
       
    87 // CUPnPValueStateMachine::CopyValues
       
    88 // copies renderer-specific cached values from another instance
       
    89 // --------------------------------------------------------------------------
       
    90 //
       
    91 void CUPnPValueStateMachine::CopyValues(
       
    92     const CUPnPValueStateMachine& aOther )
       
    93     {
       
    94     iRendererVolume = aOther.iRendererVolume;
       
    95     iRendererMuted = aOther.iRendererMuted;
       
    96     }
       
    97 
       
    98 // --------------------------------------------------------------------------
       
    99 // CUPnPValueStateMachine::ValidatePropertyInState
       
   100 // defines the rules of getting / setting in different states
       
   101 // --------------------------------------------------------------------------
       
   102 //
       
   103 CUPnPValueStateMachine::TValidationResult
       
   104     CUPnPValueStateMachine::ValidatePropertyInState(
       
   105         TMPXPlaybackProperty aProperty,
       
   106         TBool aSetting,
       
   107         TInt aPlayerState,
       
   108         TBool aIsReady )
       
   109     {
       
   110     switch( aProperty )
       
   111         {
       
   112         case EPbPropertyMaxVolume: // fall through
       
   113         case EPbPropertyRemote: // fall through
       
   114         case EPbPropertySupportedFeatures:
       
   115             {
       
   116             // allow getting in all states,
       
   117             // trying to set will result to error
       
   118             if ( !aSetting )
       
   119                 {
       
   120                 return EHandleStatic;
       
   121                 }
       
   122             else
       
   123                 {
       
   124                 return EErrorNotSupported;
       
   125                 }
       
   126             }
       
   127         case EPbPropertyVolume: // fall through
       
   128         case EPbPropertyMute:
       
   129             {            
       
   130             // allow volume get/set after initialisation when remote device
       
   131             // is ready. In other states respond with error
       
   132             if ( aPlayerState ==
       
   133                 CUPnPMusicPlayer::EStateActive )
       
   134                 {
       
   135                 if( !aIsReady )
       
   136                     {
       
   137                     return EErrorNotReady;
       
   138                     }
       
   139                 else
       
   140                     {
       
   141                     return EHandle;
       
   142                     }
       
   143                 }
       
   144             else if ( aPlayerState ==
       
   145                 CUPnPMusicPlayer::EStatePreInitialized ||
       
   146                 aPlayerState ==
       
   147                 CUPnPMusicPlayer::EStateWaiting ||
       
   148                 aPlayerState ==
       
   149                 CUPnPMusicPlayer::EStateActiveForceInitialise )
       
   150                 {
       
   151                 return EHandle;
       
   152                 }
       
   153             else
       
   154                 {
       
   155                 return EErrorNotReady;
       
   156                 }
       
   157             }
       
   158         case EPbPropertyDuration:
       
   159             {
       
   160             // duration setting is not allowed
       
   161             // getting is allowed after initialised, but will result
       
   162             // to returning plain zero in other states except active
       
   163             // when it is actually asked from the device
       
   164             if ( aSetting )
       
   165                 {
       
   166                 return EErrorNotSupported;
       
   167                 }
       
   168             else if ( aPlayerState ==
       
   169                 CUPnPMusicPlayer::EStateActive )
       
   170                 {
       
   171                 if( aIsReady )
       
   172                     {
       
   173                     return EHandle;
       
   174                     }
       
   175                 else
       
   176                     {
       
   177                     // On active state but device is not ready ->
       
   178                     // Use initial values.
       
   179                     return EHandleStatic;
       
   180                     }
       
   181                 }
       
   182             else if ( aPlayerState ==
       
   183                 CUPnPMusicPlayer::EStatePreInitialized ||
       
   184                 aPlayerState ==
       
   185                 CUPnPMusicPlayer::EStateWaiting ||
       
   186                 aPlayerState ==
       
   187                 CUPnPMusicPlayer::EStateActiveForceInitialise )
       
   188                 {
       
   189                 return EHandleStatic;
       
   190                 }
       
   191             else
       
   192                 {
       
   193                 return EErrorNotReady;
       
   194                 }
       
   195             }
       
   196         case EPbPropertyPosition:
       
   197             {
       
   198             // position get/set is allowed after init when remote device 
       
   199             // is ready. Only active state it will result to real action
       
   200             if ( aPlayerState ==
       
   201                 CUPnPMusicPlayer::EStateActive )
       
   202                 {
       
   203                 if( aIsReady )
       
   204                     {
       
   205                     return EHandle;
       
   206                     }
       
   207                 else
       
   208                     {
       
   209                     // On active state but device is not ready ->
       
   210                     // Use initial values.
       
   211                     return EHandleStatic;
       
   212                     }
       
   213                 }
       
   214             else if ( aPlayerState ==
       
   215                 CUPnPMusicPlayer::EStatePreInitialized ||
       
   216                 aPlayerState ==
       
   217                 CUPnPMusicPlayer::EStateWaiting ||
       
   218                 aPlayerState ==
       
   219                 CUPnPMusicPlayer::EStateActiveForceInitialise )
       
   220                 {
       
   221                 return EHandleStatic;
       
   222                 }
       
   223             else
       
   224                 {
       
   225                 return EErrorNotReady;
       
   226                 }
       
   227             }
       
   228         default:
       
   229             {
       
   230             // unsupported property
       
   231             return EErrorNotSupported;
       
   232             }
       
   233         }
       
   234     }
       
   235 
       
   236 
       
   237 // --------------------------------------------------------------------------
       
   238 // CUPnPValueStateMachine::SetL
       
   239 // --------------------------------------------------------------------------
       
   240 //
       
   241 void CUPnPValueStateMachine::SetL( TMPXPlaybackProperty aProperty,
       
   242     TInt aValue )
       
   243     {
       
   244     // Check if volume or mute is supported by device
       
   245     if( ( aProperty == EPbPropertyVolume && 
       
   246           !iParent.UsedRendererDevice().VolumeCapability() ) ||
       
   247         ( aProperty == EPbPropertyMute && 
       
   248           !iParent.UsedRendererDevice().MuteCapability() )      
       
   249       ) 
       
   250         {
       
   251         __LOG( "ValueStateMachine::SetL - \
       
   252         Request is not supported by device" );
       
   253         iParent.Observer().HandlePluginEvent( 
       
   254             MMPXPlaybackPluginObserver::EPSetComplete,
       
   255            (TInt)aProperty, KErrNotSupported );
       
   256             
       
   257         return;
       
   258         }
       
   259 
       
   260     // Check from queue if alredy requested.
       
   261     if( FoundFromQueue( aProperty ) )
       
   262         {
       
   263         __LOG( "ValueStateMachine::SetL: Volume query Ignored!" );
       
   264         // Ignore
       
   265         return;
       
   266         }
       
   267     
       
   268     if ( !iCurrentOperation.None() )
       
   269         {
       
   270         __LOG( "ValueStateMachine::SetL - Append to queue" );
       
   271         iOperationQueue.AppendL( TOperation( aProperty, aValue ) );
       
   272         return;
       
   273         }
       
   274 
       
   275     switch( aProperty )
       
   276         {
       
   277         case EPbPropertyVolume:
       
   278             {               
       
   279             __LOG1( "ValueStateMachine: SetVolume(%d)",
       
   280                 aValue );
       
   281             // Set the volume, do a sanity check
       
   282             if( aValue < KDefaultMinVolume || aValue > KDefaultMaxVolume )
       
   283                 {
       
   284                 // Given value out of range
       
   285                 CheckOperationInQueueL();
       
   286                 iParent.Observer().HandlePluginEvent( 
       
   287                     MMPXPlaybackPluginObserver::EPSetComplete,
       
   288                     aProperty, KErrArgument );
       
   289                 }
       
   290             else if ( aValue == iRendererVolume )
       
   291                 {
       
   292                 // re-setting the same volume
       
   293                 if ( iRendererMuted )
       
   294                     {
       
   295                     MuteRequestL( 0 );
       
   296                     }
       
   297                 iParent.Observer().HandlePluginEvent( 
       
   298                     MMPXPlaybackPluginObserver::EPSetComplete,
       
   299                     aProperty, KErrNone );
       
   300                 }
       
   301             else
       
   302                 {
       
   303                 iCurrentOperation.Set( aProperty, aValue );
       
   304                 iRendererSession.SetVolumeL( aValue );
       
   305                 if ( iRendererMuted )
       
   306                     {
       
   307                     // unmute after volume has been adjusted
       
   308                     MuteRequestL( 0 );
       
   309                     }
       
   310                 }        
       
   311             break;
       
   312             }
       
   313         case EPbPropertyMute:
       
   314             {
       
   315             __LOG1( "ValueStateMachine: SetMute(%d)",
       
   316                 aValue );
       
   317             if( aValue != 0 && iRendererMuted != 1 )
       
   318                 {
       
   319                 // set mute on
       
   320                 iCurrentOperation.Set( aProperty, 1 );
       
   321                 iRendererSession.SetMuteL( ETrue );
       
   322                 }
       
   323             else if ( aValue == 0 && iRendererMuted != 0 )
       
   324                 {
       
   325                 // set mute off
       
   326                 iCurrentOperation.Set( aProperty, 0 );
       
   327                 iRendererSession.SetMuteL( EFalse );
       
   328                 }
       
   329             else
       
   330                 {
       
   331                 // mute is already in requested state
       
   332                 CheckOperationInQueueL();
       
   333                 iParent.Observer().HandlePluginEvent( 
       
   334                     MMPXPlaybackPluginObserver::EPSetComplete,
       
   335                     aProperty, KErrNone );
       
   336                 }
       
   337             break;
       
   338             }
       
   339         default: // Given property is not supported
       
   340             {
       
   341             __LOG( "ValueStateMachine: Set - default" );
       
   342             CheckOperationInQueueL();
       
   343             iParent.Observer().HandlePluginEvent( 
       
   344                 MMPXPlaybackPluginObserver::EPSetComplete,
       
   345                 aProperty, KErrNotSupported );
       
   346             break;
       
   347             }    
       
   348         }
       
   349  
       
   350     }
       
   351     
       
   352 // --------------------------------------------------------------------------
       
   353 // CUPnPValueStateMachine::ValueL
       
   354 // --------------------------------------------------------------------------
       
   355 //
       
   356 void CUPnPValueStateMachine::ValueL( TMPXPlaybackProperty aProperty )
       
   357     {
       
   358     // Check if volume or mute is supported by device
       
   359     if( ( aProperty == EPbPropertyVolume && 
       
   360           !iParent.UsedRendererDevice().VolumeCapability() ) ||
       
   361         ( aProperty == EPbPropertyMute && 
       
   362           !iParent.UsedRendererDevice().MuteCapability() )      
       
   363       ) 
       
   364         {
       
   365         __LOG( "ValueStateMachine::ValueL - \
       
   366         Request is not supported by device" );
       
   367         iParent.Observer().HandlePluginEvent( 
       
   368             MMPXPlaybackPluginObserver::EPSetComplete,
       
   369            (TInt)aProperty, KErrNotSupported );
       
   370             
       
   371         return;
       
   372         }
       
   373     
       
   374     if ( !iCurrentOperation.None() )
       
   375         {
       
   376         __LOG( "ValueStateMachine::ValueL - Append to queue" );
       
   377         iOperationQueue.AppendL( TOperation( aProperty ) );
       
   378         return;
       
   379         }
       
   380 
       
   381     switch( aProperty )
       
   382         {
       
   383         case EPbPropertyVolume:
       
   384             {
       
   385             __LOG( "ValueStateMachine: Value(volume)" );
       
   386             iRendererSession.GetVolumeL();
       
   387             iCurrentOperation.Set( aProperty );
       
   388             break;
       
   389             }
       
   390         case EPbPropertyMute:
       
   391             {
       
   392             __LOG( "ValueStateMachine: Value(mute)" );
       
   393             iRendererSession.GetMuteL();
       
   394             iCurrentOperation.Set( aProperty );
       
   395             break;
       
   396             }
       
   397         case EPbPropertyDuration:
       
   398             {
       
   399             __LOG( "ValueStateMachine: Value(duration)" );
       
   400             if ( iParent.Track().TrackDuration() > 0 )
       
   401                 {
       
   402                 // duration found in cache
       
   403                 CheckOperationInQueueL();
       
   404                 iParent.Observer().HandleProperty( aProperty,
       
   405                     iParent.Track().TrackDuration(), KErrNone );
       
   406                 }
       
   407             else
       
   408                 {
       
   409                 iRendererSession.GetPositionInfoL();
       
   410                 iCurrentOperation.Set( aProperty );
       
   411                 }
       
   412             break;
       
   413             }
       
   414         case EPbPropertyPosition:
       
   415             {
       
   416             __LOG( "ValueStateMachine: Value(position)" );
       
   417             iRendererSession.GetPositionInfoL();
       
   418             iCurrentOperation.Set( aProperty );
       
   419             break;
       
   420             }
       
   421         default:
       
   422             {
       
   423             __PANICD( __FILE__, __LINE__ );
       
   424             break;
       
   425             }    
       
   426         }
       
   427     }
       
   428 
       
   429 
       
   430 // --------------------------------------------------------------------------
       
   431 // CUPnPValueStateMachine::ValueStatic
       
   432 // --------------------------------------------------------------------------
       
   433 //
       
   434 void CUPnPValueStateMachine::ValueStatic(
       
   435     TMPXPlaybackProperty aProperty,
       
   436     MMPXPlaybackPluginObserver& aPlaybackObs )
       
   437     {
       
   438     switch( aProperty )
       
   439         {
       
   440         case EPbPropertyMaxVolume:
       
   441             {
       
   442             __LOG( "ValueStateMachine: ValueStatic(max volume)" );
       
   443             aPlaybackObs.HandleProperty( aProperty,
       
   444                 KDefaultMaxVolume, KErrNone );
       
   445             break;
       
   446             }
       
   447          case EPbPropertyRemote:
       
   448             {
       
   449             __LOG( "ValueStateMachine: ValueStatic(remote)" );
       
   450             aPlaybackObs.HandleProperty( aProperty,
       
   451                 (TInt)EFalse, KErrNone );
       
   452             break;
       
   453             }
       
   454         case EPbPropertySupportedFeatures:
       
   455             {
       
   456             __LOG( "ValueStateMachine: ValueStatic(features)" );
       
   457             // No support for any features
       
   458             TInt supportedFeatures = 0;              
       
   459             aPlaybackObs.HandleProperty( aProperty,
       
   460                 supportedFeatures, KErrNone );
       
   461             break;
       
   462             }
       
   463         case EPbPropertyDuration:
       
   464             {
       
   465             __LOG( "ValueStateMachine: ValueStatic(duration)" );
       
   466             TInt initialDuration = 0;
       
   467             aPlaybackObs.HandleProperty( aProperty,
       
   468                 initialDuration, KErrNone );
       
   469             break;
       
   470             }
       
   471         case EPbPropertyPosition:
       
   472             {
       
   473             __LOG( "ValueStateMachine: ValueStatic(position)" );
       
   474             TInt initialPosition = 1;
       
   475             aPlaybackObs.HandleProperty( aProperty,
       
   476                 initialPosition, KErrNone );
       
   477             break;
       
   478             }
       
   479         default:
       
   480             {
       
   481             __PANICD( __FILE__, __LINE__ );
       
   482             break;
       
   483             }    
       
   484         }
       
   485     }
       
   486 
       
   487 // --------------------------------------------------------------------------
       
   488 // CUPnPValueStateMachine::DurationQueryL
       
   489 // --------------------------------------------------------------------------
       
   490 //    
       
   491 void CUPnPValueStateMachine::DurationQueryL()
       
   492     {
       
   493     // here we could check if the duration is already present in
       
   494     // iParent.track() however it was decided that we check the duration
       
   495     // from renderer anyway and trust the renderer's duration more.
       
   496     if ( !iCurrentOperation.None() )
       
   497         {
       
   498         __LOG( "ValueStateMachine::DurationQueryL - Append to queue" );
       
   499         iOperationQueue.AppendL( EOperationDurationQuery );
       
   500         return;
       
   501         }
       
   502 
       
   503     __LOG( "ValueStateMachine::DurationQueryL" );
       
   504     iRendererSession.GetPositionInfoL();
       
   505     iCurrentOperation = EOperationDurationQuery;
       
   506     }
       
   507     
       
   508 // --------------------------------------------------------------------------
       
   509 // CUPnPValueStateMachine::PositionQueryL
       
   510 // --------------------------------------------------------------------------
       
   511 //    
       
   512 void CUPnPValueStateMachine::PositionQueryL()
       
   513     {
       
   514     __LOG( "ValueStateMachine::PositionQueryL" );
       
   515     
       
   516     if ( !iCurrentOperation.None() )
       
   517         {
       
   518         __LOG( "ValueStateMachine::PositionQueryL - Append to queue" );
       
   519         iOperationQueue.AppendL( EOperationPositionQuery );
       
   520         return;
       
   521         }
       
   522     iRendererSession.GetPositionInfoL();
       
   523     iCurrentOperation = EOperationPositionQuery;
       
   524     }
       
   525 
       
   526 // --------------------------------------------------------------------------
       
   527 // CUPnPValueStateMachine::VolumeQueryL
       
   528 // --------------------------------------------------------------------------
       
   529 //    
       
   530 void CUPnPValueStateMachine::VolumeQueryL()
       
   531     {
       
   532     // Check if volume feature is supported by device.
       
   533     if( iParent.UsedRendererDevice().VolumeCapability() )
       
   534         {
       
   535         if ( iRendererVolume != KErrNotFound )
       
   536             {
       
   537             // Volume query not required - already cached.
       
   538             return;
       
   539             }
       
   540 
       
   541         if ( !iCurrentOperation.None() )
       
   542             {
       
   543             __LOG( "ValueStateMachine::VolumeQueryL - Append to queue" );
       
   544             iOperationQueue.AppendL( EOperationVolumeQuery );
       
   545             return;
       
   546         }
       
   547 
       
   548         __LOG( "ValueStateMachine::VolumeQueryL" );
       
   549         iRendererSession.GetVolumeL();
       
   550         iCurrentOperation = EOperationVolumeQuery;
       
   551         }
       
   552     else
       
   553         {
       
   554         // Get volume is not supported. Do nothing.
       
   555         }
       
   556     }
       
   557 
       
   558 // --------------------------------------------------------------------------
       
   559 // CUPnPValueStateMachine::MuteRequestL
       
   560 // --------------------------------------------------------------------------
       
   561 //    
       
   562 void CUPnPValueStateMachine::MuteRequestL( TInt aMute )
       
   563     {
       
   564     if ( !iCurrentOperation.None() )
       
   565         {
       
   566         __LOG( "ValueStateMachine::MuteRequestL - Append to queue" );
       
   567         iOperationQueue.AppendL( TOperation( EOperationMute, aMute ) );
       
   568         return;
       
   569         }
       
   570 
       
   571     __LOG1( "ValueStateMachine: MuteRequest(%d)", aMute );
       
   572     if( aMute != 0 && iRendererMuted != 1 )
       
   573         {
       
   574         // set mute on
       
   575         iCurrentOperation = EOperationMute;
       
   576         iRendererSession.SetMuteL( ETrue );
       
   577         }
       
   578     else if ( aMute == 0 && iRendererMuted != 0 )
       
   579         {
       
   580         // set mute off
       
   581         iCurrentOperation = EOperationMute;
       
   582         iRendererSession.SetMuteL( EFalse );
       
   583         }
       
   584     else
       
   585         {
       
   586         // mute is already in requested state
       
   587         CheckOperationInQueueL();
       
   588         }
       
   589     }
       
   590 
       
   591 // --------------------------------------------------------------------------
       
   592 // CUPnPValueStateMachine::VolumeResult
       
   593 // --------------------------------------------------------------------------
       
   594 //
       
   595 void CUPnPValueStateMachine::VolumeResult( TInt aError, TInt aVolumeLevel,
       
   596     TBool aActionResponse )
       
   597     {
       
   598     aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
       
   599     // If response for get volume
       
   600     
       
   601     if( aActionResponse )
       
   602         {
       
   603         if (aError == KErrNone)
       
   604             {
       
   605             iRendererVolume = aVolumeLevel;
       
   606             }
       
   607         
       
   608         if( iCurrentOperation.Compare( EOperationValue, EPbPropertyVolume ) )
       
   609             {
       
   610             __LOG( "ValueStateMachine::VolumeResult: Value resp." );
       
   611             
       
   612             iCurrentOperation.Reset();
       
   613             TRAP_IGNORE( CheckOperationInQueueL() );
       
   614             iParent.Observer().HandleProperty( EPbPropertyVolume,
       
   615                 iRendererVolume, aError );
       
   616             }
       
   617         else if( iCurrentOperation.Compare( EOperationSet, 
       
   618             EPbPropertyVolume ) )
       
   619             {
       
   620             __LOG( "ValueStateMachine::VolumeResult: Set resp." );
       
   621             iCurrentOperation.Reset();
       
   622             TRAP_IGNORE( CheckOperationInQueueL() );
       
   623             iParent.Observer().HandlePluginEvent( 
       
   624                 MMPXPlaybackPluginObserver::EPSetComplete,
       
   625                 (TInt)EPbPropertyVolume, aError );
       
   626             }
       
   627         else if ( iCurrentOperation == EOperationVolumeQuery )
       
   628             {
       
   629             __LOG1("VolumeQueryResult: Volume query resp err=%d", aError );
       
   630             
       
   631             if ( aError == KErrNone )
       
   632                 {
       
   633                 iParent.Observer().HandlePluginEvent(
       
   634                     MMPXPlaybackPluginObserver::EPVolumeChanged,
       
   635                     iRendererVolume, aError );
       
   636                 }
       
   637             
       
   638             iCurrentOperation.Reset();
       
   639             TRAP_IGNORE( CheckOperationInQueueL() );
       
   640             }
       
   641         else
       
   642             {         
       
   643             iCurrentOperation.Reset();
       
   644             __LOG( "ValueStateMachine::VolumeResult: no request?" );
       
   645             }
       
   646         }
       
   647     else // Volume changed from device
       
   648         {
       
   649         // Ignore volume events from device if volume control 
       
   650         // is ongoing on handset.
       
   651         if( iCurrentOperation.Compare( EOperationSet, EPbPropertyVolume ) )
       
   652             {
       
   653             return;
       
   654             }
       
   655         
       
   656         if (aError == KErrNone)
       
   657             {
       
   658             iRendererVolume = aVolumeLevel;
       
   659             }
       
   660         
       
   661         if ( !iRendererMuted )
       
   662             {
       
   663             __LOG1( "ValueStateMachine::VolumeResult: from device: (%d)",
       
   664                 aVolumeLevel );
       
   665             iParent.Observer().HandlePluginEvent( 
       
   666                 MMPXPlaybackPluginObserver::EPVolumeChanged,
       
   667                 iRendererVolume, aError );
       
   668             }
       
   669         else
       
   670             {
       
   671             __LOG( "ValueStateMachine::VolumeResult: from device (muted)" );
       
   672             }
       
   673         }
       
   674     }
       
   675     
       
   676 // --------------------------------------------------------------------------
       
   677 // CUPnPValueStateMachine::MuteResult
       
   678 // --------------------------------------------------------------------------
       
   679 //    
       
   680 void CUPnPValueStateMachine::MuteResult( TInt aError, TBool aMute, 
       
   681     TBool aActionResponse )
       
   682     {
       
   683     aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
       
   684     // Response for set mute
       
   685     if( aActionResponse )
       
   686         {
       
   687         if( iCurrentOperation.Compare( EOperationValue, EPbPropertyMute ) )
       
   688             {
       
   689             __LOG( "ValueStateMachine::MuteResult: Value resp." );
       
   690             iRendererMuted = aMute;
       
   691             iCurrentOperation.Reset();
       
   692             TRAP_IGNORE( CheckOperationInQueueL() );
       
   693             iParent.Observer().HandleProperty( EPbPropertyMute,
       
   694                 (TInt)aMute, aError );
       
   695             }
       
   696         else if ( iCurrentOperation.Compare( EOperationSet,
       
   697             EPbPropertyMute ) )
       
   698             {
       
   699             __LOG( "ValueStateMachine::MuteResult: Set resp." );
       
   700             iRendererMuted = aMute;
       
   701             iCurrentOperation.Reset();
       
   702             TRAP_IGNORE( CheckOperationInQueueL() );
       
   703             iParent.Observer().HandlePluginEvent( 
       
   704                 MMPXPlaybackPluginObserver::EPSetComplete,
       
   705                 (TInt)EPbPropertyMute, aError );
       
   706             }
       
   707         else if ( iCurrentOperation == EOperationMute )
       
   708             {
       
   709             // internal operation, no event.
       
   710             iRendererMuted = aMute;
       
   711             iCurrentOperation.Reset();
       
   712             TRAP_IGNORE( CheckOperationInQueueL() );
       
   713             }
       
   714         else
       
   715             {
       
   716             iRendererMuted = aMute;
       
   717             iCurrentOperation.Reset();
       
   718             __LOG( "ValueStateMachine::MuteResult: no request?" );
       
   719             }
       
   720         }
       
   721     else // Mute changed from device
       
   722         {
       
   723         __LOG( "ValueStateMachine::MuteResult: Mute changed from device" );
       
   724         
       
   725         if( aMute )
       
   726             {
       
   727             iRendererMuted = ETrue;
       
   728             iParent.Observer().HandlePluginEvent(
       
   729                 MMPXPlaybackPluginObserver::EPVolumeChanged,
       
   730                 0, aError );
       
   731             }
       
   732         else
       
   733             {
       
   734             iRendererMuted = EFalse;
       
   735             iParent.Observer().HandlePluginEvent(
       
   736                 MMPXPlaybackPluginObserver::EPVolumeChanged,
       
   737                 iRendererVolume, aError );
       
   738             }
       
   739         }
       
   740     }
       
   741 
       
   742 // --------------------------------------------------------------------------
       
   743 // CUPnPValueStateMachine::PositionInfoResult
       
   744 // --------------------------------------------------------------------------
       
   745 //
       
   746 void CUPnPValueStateMachine::PositionInfoResult( TInt aStatus,
       
   747     const TDesC8& aTrackPosition, const TDesC8& aTrackLength )
       
   748     {                      
       
   749     // Check if position info was asked
       
   750     if( iCurrentOperation.Compare( EOperationValue, EPbPropertyPosition ) )
       
   751         {
       
   752         __LOG1( "Position response err=%d", aStatus );
       
   753         TInt ms = 0;
       
   754         if( aStatus == KErrNone )
       
   755             {
       
   756             // Convert the descriptor to integer value
       
   757             aStatus = UPnPItemUtility::UPnPDurationAsMilliseconds(
       
   758                 aTrackPosition, ms );
       
   759             __LOG2( "ValueStateMachine::PositionInfoResult position=%d err=%d",
       
   760                 ms, aStatus );
       
   761             }
       
   762         iCurrentOperation.Reset();
       
   763         TRAP_IGNORE( CheckOperationInQueueL() );
       
   764         
       
   765         // Use initial position value in case of errors or position 0.
       
   766         // This will guarantee that in case of unpause, SetPosition 
       
   767         // is called with real value even if remote player does not
       
   768         // return real value for getposition call. Note that 
       
   769         // SetPosition(0) is used when user really wants to move to
       
   770         // track beginning.
       
   771         if( aStatus != KErrNone )
       
   772             {
       
   773             // GetPositionInfo is not supported by used device.
       
   774             iParent.Observer().HandleProperty( EPbPropertyPosition, 1,
       
   775                 KErrNotSupported );
       
   776             }
       
   777         else
       
   778             {
       
   779             if( ms == 0 )
       
   780                 {
       
   781                 ms = 1;
       
   782                 }
       
   783             iParent.Observer().HandleProperty( EPbPropertyPosition, ms,
       
   784                 aStatus );
       
   785             }
       
   786         }
       
   787     else if ( iCurrentOperation == EOperationPositionQuery )
       
   788         {
       
   789         __LOG1( "PositionQuery response err=%d", aStatus );
       
   790         TInt ms = 0;
       
   791         if( aStatus == KErrNone )
       
   792             {
       
   793             // Convert the descriptor to integer value
       
   794             aStatus = UPnPItemUtility::UPnPDurationAsMilliseconds(
       
   795                 aTrackPosition, ms );
       
   796             __LOG2( "ValueStateMachine::PositionInfoResult position=%d err=%d",
       
   797                 ms, aStatus );
       
   798             }
       
   799         iCurrentOperation.Reset();
       
   800         TRAP_IGNORE( CheckOperationInQueueL() );
       
   801         
       
   802         if( aStatus == KErrNone )
       
   803             {
       
   804             if( ms == 0 )
       
   805                 {
       
   806                 ms = 1;
       
   807                 }
       
   808             //iParent.Observer().HandlePluginEvent( 
       
   809             //MMPXPlaybackPluginObserver::EPPositionChanged, ms, KErrNone );
       
   810             }
       
   811         }
       
   812     // Check if duration info was asked    
       
   813     else if( iCurrentOperation.Compare( EOperationValue, 
       
   814         EPbPropertyDuration ) )
       
   815         {
       
   816         __LOG1( "Duration response err=%d", aStatus );
       
   817         TInt ms = 0;
       
   818         if( aStatus == KErrNone )
       
   819             {
       
   820             aStatus = UPnPItemUtility::UPnPDurationAsMilliseconds(
       
   821                 aTrackLength, ms );
       
   822             __LOG2( "ValueStateMachine::PositionInfoResult -\
       
   823             duration=%d err=%d", ms, aStatus );
       
   824 
       
   825             if ( aStatus == KErrNone )
       
   826                 {
       
   827                 iParent.Track().SetTrackDuration( ms );
       
   828                 }
       
   829             }
       
   830         iCurrentOperation.Reset();
       
   831         TRAP_IGNORE( CheckOperationInQueueL() );
       
   832         
       
   833         if( aStatus == KErrNotSupported )
       
   834             {
       
   835             // GetDuration is not supported by used device.
       
   836             // Use initial duration value (1). It will guarantee that in
       
   837             // case of unpause, SetPosition is called with real value even
       
   838             // if remote player does not return real value for getposition
       
   839             // call. Note that SetPosition(0) is used when user really wants
       
   840             // to move to track beginning.
       
   841             iParent.Observer().HandleProperty( EPbPropertyDuration, 1,
       
   842                 KErrNone );
       
   843             }
       
   844         else
       
   845             {
       
   846             iParent.Observer().HandleProperty( EPbPropertyDuration,
       
   847                 ms, aStatus );
       
   848             }
       
   849         }
       
   850     else if ( iCurrentOperation == EOperationDurationQuery )
       
   851         {
       
   852         __LOG1( "DurationQuery response err=%d", aStatus );
       
   853         TInt ms = 0;
       
   854         if( aStatus == KErrNone )
       
   855             {
       
   856             aStatus = UPnPItemUtility::UPnPDurationAsMilliseconds(
       
   857                 aTrackLength, ms );
       
   858             __LOG2( "ValueStateMachine::PositionInfoResult - \
       
   859             duration=%d err=%d",
       
   860                 ms, aStatus );
       
   861             if ( aStatus == KErrNone )
       
   862                 {
       
   863                 iParent.Track().SetTrackDuration( ms );
       
   864                 }
       
   865             }
       
   866         iCurrentOperation.Reset();
       
   867         TRAP_IGNORE( CheckOperationInQueueL() );
       
   868 
       
   869         if ( iParent.Track().TrackDuration() > 0 && aStatus == KErrNone )
       
   870             {
       
   871             iParent.Observer().HandlePluginEvent( 
       
   872                 MMPXPlaybackPluginObserver::EPDurationChanged,
       
   873                 iParent.Track().TrackDuration(), KErrNone );
       
   874             }
       
   875         }
       
   876     else
       
   877         {
       
   878         __LOG( "ValueStateMachine::PositionInfoResult: no request?" );
       
   879         }
       
   880     }
       
   881 
       
   882 
       
   883 
       
   884 // --------------------------------------------------------------------------
       
   885 // CUPnPValueStateMachine::Cancel
       
   886 // --------------------------------------------------------------------------
       
   887 //
       
   888 void CUPnPValueStateMachine::Cancel()
       
   889     {
       
   890     // reset current operation and empty the queue -> no callbacks.
       
   891     iCurrentOperation.Reset();
       
   892     iOperationQueue.Reset();
       
   893     }
       
   894 
       
   895 // --------------------------------------------------------------------------
       
   896 // CUPnPValueStateMachine::CheckOperationInQueueL
       
   897 // Checks if operations are in the queue, and executes
       
   898 // --------------------------------------------------------------------------
       
   899 //   
       
   900 void CUPnPValueStateMachine::CheckOperationInQueueL()
       
   901     {
       
   902     if ( !iCurrentOperation.None() )
       
   903         {
       
   904         // check operation though a current operation exists!
       
   905         __PANICD( __FILE__, __LINE__ );
       
   906         return;
       
   907         }
       
   908 
       
   909     if ( iOperationQueue.Count() > 0 )
       
   910         {
       
   911         TOperation op = iOperationQueue[0];
       
   912         iOperationQueue.Remove(0);
       
   913         if ( op == EOperationValue )
       
   914             {
       
   915             ValueL( op.iProperty );
       
   916             }
       
   917         else if ( op == EOperationSet )
       
   918             {
       
   919             SetL( op.iProperty, op.iValue );
       
   920             }
       
   921         else if ( op == EOperationDurationQuery )
       
   922             {
       
   923             DurationQueryL();
       
   924             }
       
   925         else if ( op == EOperationVolumeQuery )
       
   926             {
       
   927             VolumeQueryL();
       
   928             }
       
   929         else if ( op == EOperationPositionQuery )
       
   930             {
       
   931             PositionQueryL();
       
   932             }            
       
   933         else if ( op == EOperationMute )
       
   934             {
       
   935             MuteRequestL( op.iValue );
       
   936             }
       
   937         else
       
   938             {
       
   939             __PANICD( __FILE__, __LINE__ );
       
   940             }
       
   941         }
       
   942     }
       
   943 
       
   944 // --------------------------------------------------------------------------
       
   945 // CUPnPValueStateMachine::FoundFromQueue
       
   946 // Checks if operations are in the queue
       
   947 // --------------------------------------------------------------------------
       
   948 //   
       
   949 TBool CUPnPValueStateMachine::FoundFromQueue(TMPXPlaybackProperty aProperty)
       
   950     {    
       
   951     TBool found = EFalse;
       
   952     TInt count = iOperationQueue.Count();
       
   953 
       
   954     for( TInt i = 0; i < count; i++ )
       
   955         {
       
   956         TOperation op = iOperationQueue[i];
       
   957         if( op.iProperty == aProperty )
       
   958             {
       
   959             found = ETrue;
       
   960             break;
       
   961             }
       
   962         }
       
   963     return found;
       
   964     }
       
   965 
       
   966