upnpmpxplugins/upnpplaybackplugins/src/upnpmusicplayer.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:      Plugin for playing files in a remote upnp renderer
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 // INCLUDES
       
    24 #include "upnpavcontrollerfactory.h"
       
    25 #include "upnpavcontroller.h"
       
    26 #include "upnpfileutility.h"
       
    27 #include "upnpavrenderingsession.h"
       
    28 #include "upnpavdevice.h"
       
    29 #include <mpxplaybackpluginobserver.h>
       
    30 
       
    31 #include "upnpmusicplayer.h"
       
    32 #include "upnpsingleton.h"
       
    33 #include "upnptrack.h"
       
    34 #include "upnpplaybackstatemachine.h"
       
    35 #include "upnpvaluestatemachine.h"
       
    36 #include "upnppluginserrortranslation.h"
       
    37 
       
    38 
       
    39 // CONSTANTS
       
    40 // ** a message to music player to complete an immediate exit
       
    41 const TInt KMusicPluginMessageExit = 3001;
       
    42 const TUid KMusicPlayerUid = { 0x200075D8 };
       
    43 
       
    44 _LIT( KStateUninitialized, "Uninitialised" );
       
    45 _LIT( KStateUninitialising, "Uninitialising" );
       
    46 _LIT( KStateInitializing, "Initializing" );
       
    47 _LIT( KStateActive, "Active" );
       
    48 _LIT( KStatePreInitializing, "PreInitializing" );
       
    49 _LIT( KStatePreInitialized, "PreInitialized" );
       
    50 _LIT( KStateWaiting, "Waiting" );
       
    51 _LIT( KStateActiveForceInit, "ActiveForceInit" );
       
    52 _LIT( KStateError, "Error" );
       
    53 _LIT( KStateUnknown, "Unknown" );
       
    54 
       
    55 
       
    56 _LIT( KComponentLogfile, "musicplugins.txt");
       
    57 #include "upnplog.h"
       
    58 
       
    59 // LOCAL FUNCTIONS
       
    60 
       
    61     /*
       
    62      * a template helper function to safely delete a pointer
       
    63      * (make sure pointer becomes NULL before delete is called)
       
    64      * 1. first copy the given pointer to a local temp variable
       
    65      * 2. then allocate a local member, then nullify the given pointer
       
    66      * 3. last, delete the temporary pointer
       
    67      */
       
    68     template <class T>
       
    69     inline void SafeDelete( T*& aPointer )
       
    70         {
       
    71         // first, store the given object into a local temp variable
       
    72         T* tempPointer = aPointer;
       
    73         // nullify the given pointer
       
    74         aPointer = 0;
       
    75         // last, delete the given object
       
    76         delete tempPointer;
       
    77         }
       
    78 
       
    79 // --------------------------------------------------------------------------
       
    80 // Static members of CUPnPMusicPlayer
       
    81 // --------------------------------------------------------------------------
       
    82 //
       
    83 
       
    84 // Pointer to the plugin that is active at the time
       
    85 CUPnPMusicPlayer* CUPnPMusicPlayer::iActivePlugIn;
       
    86 
       
    87 // Pointer to the plugini that is waiting to activate (pre-initialized)
       
    88 CUPnPMusicPlayer* CUPnPMusicPlayer::iNextPlugIn;
       
    89 
       
    90 // ======== MEMBER FUNCTIONS ========
       
    91 
       
    92 // --------------------------------------------------------------------------
       
    93 // CUPnPMusicPlayer::NewL
       
    94 // 1st phase constructor.
       
    95 // --------------------------------------------------------------------------
       
    96 //
       
    97 CUPnPMusicPlayer* CUPnPMusicPlayer::NewL( MMPXPlaybackPluginObserver& aObs )
       
    98     {
       
    99     CUPnPMusicPlayer* p = new(ELeave) CUPnPMusicPlayer( aObs );
       
   100     CleanupStack::PushL( p );
       
   101     __LOG1( "CUPnPMusicPlayer::NewL [%d]", p );
       
   102     p->ConstructL();
       
   103     CleanupStack::Pop( p );
       
   104     return p;
       
   105     }
       
   106 
       
   107 // --------------------------------------------------------------------------
       
   108 // CUPnPMusicPlayer::CUPnPMusicPlayer
       
   109 // Default constructor.
       
   110 // --------------------------------------------------------------------------
       
   111 // 
       
   112 CUPnPMusicPlayer::CUPnPMusicPlayer( MMPXPlaybackPluginObserver& aObs ) :
       
   113     iSelectedRendererIndex( KErrNotFound ),
       
   114     iPlayerState( EStateUninitialised ),
       
   115     iIsReady( EFalse )
       
   116     {   
       
   117     iObs = &aObs;
       
   118     iTrack = NULL;
       
   119     }
       
   120 
       
   121 // --------------------------------------------------------------------------
       
   122 // CUPnPMusicPlayer::ConstructL
       
   123 // --------------------------------------------------------------------------
       
   124 //
       
   125 void CUPnPMusicPlayer::ConstructL()
       
   126     {
       
   127     __LOG( "CUPnPMusicPlayer::ConstructL" );
       
   128 
       
   129     // get a handle to the shared singleton
       
   130     iSingleton = CUPnPSingleton::GetInstanceL();
       
   131     
       
   132     // audio policy
       
   133     iAudioPolicy = CUPnPAudioPolicy::NewL( *this );
       
   134     }
       
   135 
       
   136 // --------------------------------------------------------------------------
       
   137 // CUPnPMusicPlayer::~CUPnPMusicPlayer
       
   138 // Destructor.
       
   139 // --------------------------------------------------------------------------
       
   140 //
       
   141 CUPnPMusicPlayer::~CUPnPMusicPlayer()
       
   142     {
       
   143     __LOG( "CUPnPMusicPlayer::~CUPnPMusicPlayer()" );
       
   144     UninitialiseTrack( EStateNone );
       
   145             
       
   146     if( iSingleton != NULL )
       
   147         {
       
   148         CUPnPSingleton::LoseInstance( iSingleton );
       
   149         iSingleton = NULL;
       
   150         }
       
   151 
       
   152     delete iAudioPolicy;
       
   153     iAudioPolicy = 0;
       
   154     delete iSelectedRenderer;
       
   155     } 
       
   156 
       
   157 // --------------------------------------------------------------------------
       
   158 // CUPnPMusicPlayer::MatchRenderer
       
   159 // Compares renderers names
       
   160 // --------------------------------------------------------------------------
       
   161 //
       
   162 TBool CUPnPMusicPlayer::MatchRenderer(
       
   163     const CUpnpAVDevice* aRenderer ) const
       
   164     {
       
   165     if( aRenderer == NULL  )
       
   166         {
       
   167         // no renderer - using default renderer, which is always
       
   168         // the same as previously selected renderer -> ALWAYS MATCH.
       
   169         return ETrue;
       
   170         }
       
   171 
       
   172     if( iSelectedRenderer == NULL  )
       
   173         {
       
   174         // Current renderer does not exist - this should never happen.
       
   175         __PANICD( __FILE__, __LINE__ );
       
   176         return ETrue;
       
   177         }
       
   178 
       
   179     // compare renderer pointer
       
   180     if ( iSelectedRenderer == aRenderer )
       
   181         {
       
   182         return ETrue;
       
   183         }
       
   184 
       
   185     // Compare renderer UUID
       
   186     if ( iSelectedRenderer->Uuid().Compare( aRenderer->Uuid() ) == 0 )
       
   187         {
       
   188         return ETrue;
       
   189         }
       
   190     
       
   191     return EFalse;
       
   192     }
       
   193 
       
   194 
       
   195 // --------------------------------------------------------------------------
       
   196 // CUPnPMusicPlayer::UsedRendererDevice
       
   197 // Returns currently used renderer device
       
   198 // --------------------------------------------------------------------------
       
   199 //
       
   200 CUpnpAVDevice& CUPnPMusicPlayer::UsedRendererDevice() const
       
   201     {
       
   202     return *iSelectedRenderer;
       
   203     }
       
   204 
       
   205 // --------------------------------------------------------------------------
       
   206 // CUPnPMusicPlayer::SetActive
       
   207 // Set Plugin state to active.
       
   208 // --------------------------------------------------------------------------
       
   209 //
       
   210 void CUPnPMusicPlayer::SetActive( TBool aForceInitialise )
       
   211     {
       
   212     __LOG( "CUPnPMusicPlayer::SetActive" );
       
   213 
       
   214     if ( iActivePlugIn != 0 &&
       
   215         iActivePlugIn->MatchRenderer( iSelectedRenderer ) )
       
   216         {
       
   217         // Continuing playback on the same renderer.
       
   218         // copy some cached values
       
   219         // 
       
   220         iValueStateMachine->CopyValues(
       
   221             iActivePlugIn->ValueStateMachine() );
       
   222         }
       
   223 
       
   224     if( iPlayerState == EStatePreInitialized ) 
       
   225         {
       
   226         // Preinitialize is ready. Clear pointer from iNextPlugin and 
       
   227         // sets it to iActivePlugIn.
       
   228         iActivePlugIn = this;
       
   229         iNextPlugIn = NULL;
       
   230         if( aForceInitialise )
       
   231             {
       
   232             ChangeState( EStateActiveForceInitialise );
       
   233             TRAP_IGNORE( iAudioPolicy->PlayL() );
       
   234             }
       
   235         else
       
   236             {
       
   237             ChangeState( EStateActive );
       
   238             TRAP_IGNORE( iAudioPolicy->PlayL() );
       
   239             }
       
   240         }
       
   241     else if( iPlayerState == EStateWaiting )
       
   242         {
       
   243         // Used renderer does not support SetNextURI feature. Initialise
       
   244         // track by SetURI after play command.
       
   245         iActivePlugIn = this;
       
   246         iNextPlugIn = NULL;
       
   247         ChangeState( EStateActiveForceInitialise );
       
   248         }
       
   249     else if( iPlayerState == EStateActive )
       
   250         {
       
   251         // do nothing
       
   252         iActivePlugIn = this;
       
   253         iNextPlugIn = NULL;
       
   254         ChangeState( EStateActive );
       
   255         TRAP_IGNORE( iAudioPolicy->PlayL() );
       
   256         }
       
   257     else if( iPlayerState == EStatePreInitializing )
       
   258         {
       
   259         // Do nothing.
       
   260         }
       
   261     else
       
   262         {
       
   263         __LOG1( "CUPnPMusicPlayer::SetActive in wrong state %S",
       
   264             State( iPlayerState ) );
       
   265         __PANICD( __FILE__, __LINE__ );
       
   266         }   
       
   267     }
       
   268 
       
   269 // --------------------------------------------------------------------------
       
   270 // CUPnPMusicPlayer::Observer
       
   271 // --------------------------------------------------------------------------
       
   272 //
       
   273 MMPXPlaybackPluginObserver& CUPnPMusicPlayer::Observer() const
       
   274     {
       
   275     __ASSERTD( iObs != 0, __FILE__, __LINE__ );
       
   276     return *iObs;
       
   277     }
       
   278 
       
   279 // --------------------------------------------------------------------------
       
   280 // CUPnPMusicPlayer::PlaybackStateMachine
       
   281 // --------------------------------------------------------------------------
       
   282 //
       
   283 const CUPnPPlaybackStateMachine&
       
   284     CUPnPMusicPlayer::PlaybackStateMachine() const
       
   285     {
       
   286     __ASSERTD( iPlaybackStateMachine != 0, __FILE__, __LINE__ );
       
   287     return *iPlaybackStateMachine;
       
   288     }
       
   289 
       
   290 // --------------------------------------------------------------------------
       
   291 // CUPnPMusicPlayer::ValueStateMachine
       
   292 // --------------------------------------------------------------------------
       
   293 //
       
   294 const CUPnPValueStateMachine&
       
   295     CUPnPMusicPlayer::ValueStateMachine() const
       
   296     {
       
   297     __ASSERTD( iValueStateMachine != 0, __FILE__, __LINE__ );
       
   298     return *iValueStateMachine;
       
   299     }
       
   300 
       
   301 // --------------------------------------------------------------------------
       
   302 // CUPnPMusicPlayer::Track
       
   303 // --------------------------------------------------------------------------
       
   304 //
       
   305 CUPnPTrack& CUPnPMusicPlayer::Track() const
       
   306     {
       
   307     __ASSERTD( iTrack != 0, __FILE__, __LINE__ );
       
   308     return *iTrack;
       
   309     }
       
   310 
       
   311 
       
   312 // --------------------------------------------------------------------------
       
   313 // CUPnPMusicPlayer::HandlePlayStarted
       
   314 // --------------------------------------------------------------------------
       
   315 //
       
   316 void CUPnPMusicPlayer::HandlePlayStarted()
       
   317     {
       
   318     __LOG( "CUPnPMusicPlayer::HandlePlayStarted" );
       
   319 
       
   320     // Remote device is ready for give playback information 
       
   321     // (duration, position..)
       
   322     iIsReady = ETrue;
       
   323 
       
   324     // Inform user that playback is started
       
   325     iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPPlaying, 0,
       
   326         KErrNone );
       
   327 
       
   328     if( iValueStateMachine && iTrack )
       
   329         {
       
   330         // always query volume. Duration if not already exist or in 
       
   331         // case of remote track.
       
   332         TRAP_IGNORE(
       
   333             iValueStateMachine->VolumeQueryL();
       
   334             if( iTrack->TrackDuration() == 0 || iTrack->IsRemote() )
       
   335                 {
       
   336                 iValueStateMachine->DurationQueryL();
       
   337                 }
       
   338             )
       
   339         }
       
   340     }
       
   341 
       
   342 // --------------------------------------------------------------------------
       
   343 // CUPnPMusicPlayer::HandlePlayComplete
       
   344 // --------------------------------------------------------------------------
       
   345 //
       
   346 void CUPnPMusicPlayer::HandlePlayComplete()
       
   347     {
       
   348     __LOG( "CUPnPMusicPlayer::HandlePlayComplete" );
       
   349 
       
   350     iAudioPolicy->Stop();
       
   351 
       
   352     // If there is a next initialized plugin then active it
       
   353     if( iActivePlugIn == this && iNextPlugIn != 0 )
       
   354         {
       
   355         // Set iActivePlugIn to null.
       
   356         iNextPlugIn->SetActive( EFalse );   
       
   357         }
       
   358     }
       
   359 
       
   360 
       
   361 // --------------------------------------------------------------------------
       
   362 // Methods from CMPXPlaybackPlugin
       
   363 // --------------------------------------------------------------------------
       
   364 
       
   365 // --------------------------------------------------------------------------
       
   366 // CUPnPMusicPlayer::InitialiseL( const TDesC& aSong )
       
   367 // Initializes a song for playback.
       
   368 // --------------------------------------------------------------------------
       
   369 //
       
   370 void CUPnPMusicPlayer::InitialiseL( const TDesC& aSong )
       
   371     {    
       
   372     // Initialise song for play back.
       
   373     InitialiseTrackL( aSong );
       
   374     }
       
   375 
       
   376 // --------------------------------------------------------------------------
       
   377 // CUPnPMusicPlayer::InitialiseL(  RFile& aSong )
       
   378 // Initializes a song for playback.
       
   379 // --------------------------------------------------------------------------
       
   380 //   
       
   381 void CUPnPMusicPlayer::InitialiseL( RFile& aSong )
       
   382     {
       
   383     // At first get the song path from given resource file
       
   384     HBufC* tempBuf = HBufC::NewL( KMaxFileName );
       
   385     CleanupStack::PushL( tempBuf );
       
   386     TPtr ptr = tempBuf->Des();
       
   387     TInt err = aSong.FullName( ptr );
       
   388 
       
   389     // Leave if any error
       
   390     if( err != KErrNone )
       
   391         {
       
   392         User::Leave( KErrArgument );
       
   393         }
       
   394 
       
   395     // Initialise song for play back.
       
   396     InitialiseTrackL( *tempBuf );
       
   397     CleanupStack::PopAndDestroy( tempBuf );
       
   398     }
       
   399 
       
   400 // --------------------------------------------------------------------------
       
   401 // CUPnPMusicPlayer::InitialiseTrackL
       
   402 // Initializes a remote or local song for playback
       
   403 // --------------------------------------------------------------------------
       
   404 //
       
   405 void CUPnPMusicPlayer::InitialiseTrackL( const TDesC& aSong )
       
   406     {
       
   407     __LOG1( "CUPnPMusicPlayer::InitialiseTrackL [%d]", this );
       
   408     __ASSERTD( iPlayerState == EStateUninitialised, __FILE__, __LINE__ );
       
   409 
       
   410     // some state checks
       
   411     if ( iPlayerState != EStateUninitialised )
       
   412         {
       
   413         __LOG( "CUPnPMusicPlayer::InitialiseTrackL: In wrong state! " );
       
   414         User::Leave( KErrNotReady );
       
   415         }
       
   416     if( ( iActivePlugIn != NULL ) && ( iNextPlugIn != NULL ) )
       
   417         {
       
   418         __LOG( "CUPnPMusicPlayer::InitialiseTrackL - \
       
   419         More than two plugin initialisezed at the same time! " );
       
   420         User::Leave( KErrNotReady );
       
   421         }
       
   422     if( iSelectedRenderer == 0 )
       
   423         {
       
   424         __LOG( "CUPnPMusicPlayer::InitialiseTrackL - \
       
   425         Subplayer not selected " );
       
   426         User::Leave( KErrNotReady );
       
   427         }
       
   428     
       
   429     if( aSong.Length() == 0 )
       
   430         {
       
   431         User::Leave( KErrNotSupported );
       
   432         }
       
   433     
       
   434     __LOG( "CUPnPMusicPlayer::InitialiseTrackL: Start rendering session" );
       
   435     MUPnPAVRenderingSession* tempSession =
       
   436         &iSingleton->AVC().StartRenderingSessionL( *iSelectedRenderer );
       
   437         
       
   438     __LOG( "CUPnPMusicPlayer::InitialiseTrackL - \
       
   439         Set Rendering session observer" );
       
   440     // Set media observer
       
   441     tempSession->SetObserver( *this );
       
   442 
       
   443     // stop existing rendering session if exists
       
   444     if( iRendererSession )
       
   445         {
       
   446         __LOG( "CUPnPMusicPlayer::InitialiseTrackL: Stop old session" );
       
   447         // releasing local MS services is left to AVController
       
   448         iSingleton->AVC().StopRenderingSession( *iRendererSession );
       
   449         iRendererSession = 0;
       
   450         }
       
   451 
       
   452     iRendererSession = tempSession;
       
   453              
       
   454     // Set plugin to active and call SetURI if there is no track
       
   455     // playing currently or the track playing currently is in 
       
   456     // different renderer
       
   457     if( iActivePlugIn == NULL ) 
       
   458         {
       
   459         // There is no track playing currently
       
   460         iActivePlugIn = this; // Set Plugin to the active.
       
   461         ChangeState( EStateInitializing );
       
   462         }
       
   463     else // Track is currently playing.
       
   464         {
       
   465         // Check if track is playing in different renderer
       
   466         if( iActivePlugIn->MatchRenderer( iSelectedRenderer ) )
       
   467             {
       
   468             iNextPlugIn = this; // Set plugin to the next
       
   469             ChangeState( EStatePreInitializing );
       
   470             }
       
   471         else
       
   472             {
       
   473             // Track is playing but different renderer
       
   474             ChangeState( EStateInitializing );
       
   475             }
       
   476         } 
       
   477 
       
   478     // Create state machines
       
   479     iPlaybackStateMachine = CUPnPPlaybackStateMachine::NewL(
       
   480         *this, *iRendererSession );
       
   481 
       
   482     iValueStateMachine = CUPnPValueStateMachine::NewL(
       
   483         *this, *iRendererSession );
       
   484 
       
   485     // Create track object to resolving URI
       
   486     iTrack = CUPnPTrack::NewL( iSingleton->AVC() );
       
   487     iTrack->ResolveURIL( aSong, *this, CUPnPTrack::EDirectionRemote );
       
   488     }
       
   489 
       
   490 // --------------------------------------------------------------------------
       
   491 // CUPnPMusicPlayer::UninitialiseTrack
       
   492 // --------------------------------------------------------------------------
       
   493 // 
       
   494 void CUPnPMusicPlayer::UninitialiseTrack( TPlayerState aToState )
       
   495     {
       
   496     __LOG1( "CUPnPMusicPlayer::UninitialiseTrack(%S)",
       
   497         State( aToState ) );
       
   498     ChangeState( EStateUninitialising );
       
   499 
       
   500     if ( iAudioPolicy )
       
   501         {
       
   502         iAudioPolicy->Stop();
       
   503         }
       
   504     
       
   505     if ( iActivePlugIn == this )
       
   506         {
       
   507         iActivePlugIn = 0;
       
   508         }
       
   509     if ( iNextPlugIn == this )
       
   510         {
       
   511         iNextPlugIn = 0;
       
   512         }
       
   513 
       
   514     if( iPlaybackStateMachine )
       
   515         {
       
   516         delete iPlaybackStateMachine;
       
   517         iPlaybackStateMachine = 0;
       
   518         }
       
   519 
       
   520     if( iValueStateMachine )
       
   521         {
       
   522         delete iValueStateMachine;
       
   523         iValueStateMachine = 0;
       
   524         }
       
   525 
       
   526     // Rendering session is not cleared until destructor.
       
   527     if( iRendererSession && aToState == EStateNone )
       
   528         {
       
   529         // releasing local MS services is left to AVController
       
   530         iSingleton->AVC().StopRenderingSession( *iRendererSession );
       
   531         iRendererSession = 0;
       
   532         }
       
   533 
       
   534     iSelectedRendererIndex = KErrNotFound;
       
   535     iIsReady = EFalse;
       
   536 
       
   537     if ( iTrack )
       
   538         {
       
   539         // request track to delete itself
       
   540         CUPnPTrack* tempTrack = iTrack;
       
   541         iTrack = NULL;
       
   542         tempTrack->Delete();
       
   543         }
       
   544 
       
   545     ChangeState( aToState );
       
   546     __LOG( "CUPnPMusicPlayer::UninitialiseTrack - End" );
       
   547     }
       
   548 
       
   549 // --------------------------------------------------------------------------
       
   550 // CUPnPMusicPlayer::ResolveURIComplete
       
   551 // from MUPnPTrackObserver
       
   552 // --------------------------------------------------------------------------
       
   553 // 
       
   554 void CUPnPMusicPlayer::ResolveURIComplete( TInt aError )
       
   555     {
       
   556     __LOG2( "CUPnPMusicPlayer::ResolveURIComplete in state %S [%d]",
       
   557         State( iPlayerState ), this );
       
   558 
       
   559     if ( aError == KErrNone )
       
   560         {
       
   561         // Check is local or remote
       
   562         TRAPD( error, SetURIL() );
       
   563         if ( error != KErrNone )
       
   564             {
       
   565             __LOG1("CUPnPMusicPlayer::ResolveURIComplete: leaves with %d",
       
   566                 error );
       
   567             UninitialiseTrack();
       
   568             error = TUpnpPluginsErrorTranslation::ErrorTranslate( 
       
   569                     error );
       
   570             iObs->HandlePluginEvent( 
       
   571                 MMPXPlaybackPluginObserver::EPInitialised,
       
   572                 0, error );
       
   573             }
       
   574         }
       
   575     else
       
   576         {
       
   577         __LOG1("CUPnPMusicPlayer::ResolveURIComplete: error %d",
       
   578             aError );
       
   579         UninitialiseTrack();
       
   580         aError = TUpnpPluginsErrorTranslation::ErrorTranslate( 
       
   581                 aError );
       
   582         iObs->HandlePluginEvent( 
       
   583             MMPXPlaybackPluginObserver::EPInitialised,
       
   584             0, aError );
       
   585         }
       
   586     }
       
   587 
       
   588 
       
   589 // --------------------------------------------------------------------------
       
   590 // CUPnPMusicPlayer::SetURIL
       
   591 // --------------------------------------------------------------------------
       
   592 // 
       
   593 void CUPnPMusicPlayer::SetURIL()
       
   594     {
       
   595     __LOG( "CUPnPMusicPlayer::SetURIL" );
       
   596 
       
   597     switch( iPlayerState )
       
   598         {
       
   599         case EStateInitializing: // flow through
       
   600         case EStateActiveForceInitialise:
       
   601             {
       
   602             iRendererSession->SetURIL(
       
   603                 iTrack->UpnpURI(), iTrack->UpnpItem() );
       
   604             }
       
   605             break;
       
   606         case EStatePreInitializing:
       
   607             {
       
   608             // Set NextUri if action is supported by used device
       
   609             if( iSelectedRenderer->NextAVTransportUri() )
       
   610                 {
       
   611                 __LOG( "CUPnPMusicPlayer::SetURIL - \
       
   612                 Remote:SetNextURI" );
       
   613                 
       
   614                 iRendererSession->SetNextURIL( 
       
   615                     iTrack->UpnpURI(), iTrack->UpnpItem() );
       
   616                 }
       
   617             else
       
   618                 {
       
   619                 __LOG( "CUPnPMusicPlayer::SetURI - \
       
   620                 SetNextURI is not supported by used device" );
       
   621 
       
   622                 // Used renderer does not support SetNextURI feature. 
       
   623                 // Initialise track by SetURI after play is called.
       
   624                 ChangeState( EStateWaiting );
       
   625                 iObs->HandlePluginEvent( 
       
   626                     MMPXPlaybackPluginObserver::EPInitialised,
       
   627                     iTrack->TrackDuration(), KErrNone );
       
   628                 if ( iPlayerState == EStateWaiting )
       
   629                     {
       
   630                     if( iTrack->IsRemote() )
       
   631                         {
       
   632                         iTrack->SendMediaChangedEventL( *iObs );
       
   633                         }
       
   634                     }
       
   635                 }
       
   636             }
       
   637             break;
       
   638         case EStatePauseInActiveForceInitialise:
       
   639             {
       
   640             // This case happens when active plugin is paused and user 
       
   641             // skips to the next track from UI.
       
   642             __LOG( "SetURI during EStatePauseInActiveForceInitialise" );
       
   643             iRendererSession->SetURIL(
       
   644                 iTrack->UpnpURI(), iTrack->UpnpItem() );
       
   645             }
       
   646             break;
       
   647         default:
       
   648             {
       
   649             __PANICD( __FILE__, __LINE__ );
       
   650             }
       
   651             break;
       
   652         }
       
   653 
       
   654     }
       
   655 
       
   656 // --------------------------------------------------------------------------
       
   657 // CUPnPMusicPlayer::CommandL
       
   658 // Executes a command on the selected song.
       
   659 // --------------------------------------------------------------------------
       
   660 // 
       
   661 void CUPnPMusicPlayer::CommandL( TMPXPlaybackCommand aCmd, TInt aData )
       
   662     {
       
   663     __LOG3( "CUPnPMusicPlayer::CommandL(%d) in state %S [%d]",
       
   664        aCmd, State( iPlayerState ), this );
       
   665         
       
   666     switch( iPlayerState )
       
   667         {
       
   668         case EStateUninitialised:   // fall through
       
   669         case EStateUninitialising:  // fall through
       
   670             {
       
   671             // ignore everything
       
   672             }
       
   673         case EStateError:
       
   674             {
       
   675             // Only Stop and Close will be handled.
       
   676             // All other commands ignored.
       
   677             if ( aCmd == EPbCmdStop )
       
   678                 {
       
   679                 iObs->HandlePluginEvent(
       
   680                     MMPXPlaybackPluginObserver::EPStopped,
       
   681                     KErrNone, KErrNone );
       
   682                 }
       
   683             if ( aCmd == EPbCmdClose )
       
   684                 {
       
   685                 iObs->HandlePluginEvent(
       
   686                     MMPXPlaybackPluginObserver::EPClosed,
       
   687                     KErrNone, KErrNone );
       
   688                 }
       
   689             break;
       
   690             }
       
   691         case EStateInitializing:    // fall through
       
   692         case EStatePreInitializing: // fall through
       
   693         case EStatePreInitialized:  // fall through
       
   694         case EStateWaiting:         // fall through
       
   695         case EStateActiveForceInitialise:
       
   696             {
       
   697             if( aCmd == EPbCmdStop )
       
   698                 {
       
   699                 // answer directly to stopped message
       
   700                 iObs->HandlePluginEvent(
       
   701                     MMPXPlaybackPluginObserver::EPStopped,
       
   702                     KErrNone, KErrNone );
       
   703                 }
       
   704             if( aCmd == EPbCmdPlay &&
       
   705                 ( iPlayerState == EStateActiveForceInitialise ) )
       
   706                 {
       
   707                 __LOG( "CUPnPMusicPlayer::Command(play)->SetURI" );
       
   708                 SetURIL();
       
   709                 }
       
   710             if( aCmd == EPbCmdPlay && iPlayerState == EStateWaiting )
       
   711                 {                
       
   712                 // This plugin has to be set active because track has forced
       
   713                 // to be skipped by user.
       
   714                 SetActive( ETrue );
       
   715                 SetURIL();
       
   716                 }
       
   717             if( aCmd == EPbCmdPlay && iPlayerState == EStatePreInitialized )
       
   718                 {
       
   719                 // This plugin has to be set active because track has forced
       
   720                 // to be skipped by user.
       
   721                 SetActive( ETrue );
       
   722                 SetURIL();            
       
   723                 }
       
   724             if( aCmd == EPbCmdPause && 
       
   725                 ( iPlayerState == EStateActiveForceInitialise || 
       
   726                   iPlayerState == EStateWaiting ) )
       
   727                 {
       
   728                 // This case happens when active plugin is paused and user 
       
   729                 // skips to the next track from UI -> next track must be 
       
   730                 // switched to paused state.
       
   731                 __LOG( "Pause command during EStateActiveForceInitialise" );
       
   732                 iPlayerState = EStatePauseInActiveForceInitialise;
       
   733                 SetURIL();
       
   734                 }
       
   735                 
       
   736             if ( aCmd == EPbCmdClose )
       
   737                 {
       
   738                 UninitialiseTrack();
       
   739                 iObs->HandlePluginEvent(
       
   740                     MMPXPlaybackPluginObserver::EPClosed,
       
   741                     KErrNone, KErrNone );
       
   742                 }
       
   743             break;
       
   744             }
       
   745         case EStateActive:
       
   746             {
       
   747             iPlaybackStateMachine->CommandL( aCmd );
       
   748             if( aCmd == EPbCmdStop )
       
   749                 {
       
   750                 if ( this == iActivePlugIn && iNextPlugIn != 0 )
       
   751                     {
       
   752                     __LOG( "CommandL(stop)->SetActive()" );
       
   753                     iNextPlugIn->SetActive( ETrue );
       
   754                     }
       
   755                 }
       
   756             if( aCmd == EPbCmdPause )
       
   757                 {
       
   758                 if ( this == iActivePlugIn && iNextPlugIn != 0 )
       
   759                     {
       
   760                     __LOG( "CommandL(pause)->SetActive()" );
       
   761                     iNextPlugIn->SetActive( EFalse );
       
   762                     }
       
   763                 }
       
   764             if( aCmd == EPbCmdClose )
       
   765                 {
       
   766                 if ( this == iActivePlugIn && iNextPlugIn != 0 )
       
   767                     {
       
   768                     __LOG( "CommandL(close)->SetActive()" );
       
   769                     iNextPlugIn->SetActive( ETrue );
       
   770                     }
       
   771                 UninitialiseTrack();
       
   772                 }
       
   773             break;
       
   774             }
       
   775         default:
       
   776             {
       
   777             __LOG( "CUPnPMusicPlayer::CommandL - Default" );
       
   778             break;
       
   779             } 
       
   780         }
       
   781 
       
   782     // check for messages from upnp framework (aData param)
       
   783     if ( aCmd == EPbCmdClose &&
       
   784         aData == KMusicPluginMessageExit )
       
   785         {
       
   786         __LOG( "CommandL(Close, exit) -> cleanup and terminate" );
       
   787 
       
   788         // cancel things that are ongoing
       
   789         CancelRequest();
       
   790         // clear resources
       
   791         UninitialiseTrack( EStateError );
       
   792 
       
   793         // Create event to user
       
   794         iObs->HandlePluginEvent(
       
   795             MMPXPlaybackPluginObserver::EPPlayerUnavailable,
       
   796             0, KErrDisconnected );
       
   797         }
       
   798 
       
   799     }
       
   800 
       
   801 // --------------------------------------------------------------------------
       
   802 // CUPnPMusicPlayer::SetL
       
   803 // Sets a property of the plugin.
       
   804 // --------------------------------------------------------------------------
       
   805 //
       
   806 void CUPnPMusicPlayer::SetL( TMPXPlaybackProperty aProperty, TInt aValue )
       
   807     {
       
   808     __LOG2( "CUPnPMusicPlayer::SetL in state %S [%d]",
       
   809         State( iPlayerState ), this );
       
   810 
       
   811     CUPnPValueStateMachine::TValidationResult result =
       
   812         CUPnPValueStateMachine::ValidatePropertyInState(
       
   813         aProperty, ETrue, iPlayerState, iIsReady );
       
   814 
       
   815     if ( result == CUPnPValueStateMachine::EHandle )
       
   816         {
       
   817         if ( aProperty == EPbPropertyPosition )
       
   818             {
       
   819             // Position changes are handled in playback s.m.
       
   820             iPlaybackStateMachine->PositionL( aValue );
       
   821             }
       
   822         else
       
   823             {
       
   824             // all other values in value s.m.
       
   825             iValueStateMachine->SetL( aProperty, aValue );
       
   826             }
       
   827         }
       
   828     else if ( result == CUPnPValueStateMachine::EHandleStatic )
       
   829         {
       
   830         iObs->HandlePluginEvent( 
       
   831             MMPXPlaybackPluginObserver::EPSetComplete,
       
   832             (TInt)aProperty, KErrNone );
       
   833         }
       
   834     else if ( result == CUPnPValueStateMachine::EErrorNotReady )
       
   835         {
       
   836         iObs->HandlePluginEvent( 
       
   837             MMPXPlaybackPluginObserver::EPSetComplete,
       
   838             (TInt)aProperty, KErrNotReady );
       
   839         }
       
   840     else if ( result == CUPnPValueStateMachine::EErrorNotSupported )
       
   841         {
       
   842         iObs->HandlePluginEvent( 
       
   843             MMPXPlaybackPluginObserver::EPSetComplete,
       
   844             (TInt)aProperty, KErrNotSupported );
       
   845         }
       
   846     else if ( result == CUPnPValueStateMachine::EIgnore )
       
   847         {
       
   848         // do nothing
       
   849         }
       
   850     else 
       
   851         {
       
   852         __PANICD( __FILE__, __LINE__ );
       
   853         }
       
   854     }
       
   855 
       
   856 // --------------------------------------------------------------------------
       
   857 // CUPnPMusicPlayer::ValueL
       
   858 // Gets a property of the plugin (async).
       
   859 // --------------------------------------------------------------------------
       
   860 //
       
   861 void CUPnPMusicPlayer::ValueL( TMPXPlaybackProperty aProperty ) const
       
   862     {
       
   863     __LOG2( "CUPnPMusicPlayer::ValueL in state %S [%d]",
       
   864         State( iPlayerState ), this );
       
   865 
       
   866     CUPnPValueStateMachine::TValidationResult result =
       
   867         CUPnPValueStateMachine::ValidatePropertyInState(
       
   868         aProperty, EFalse, iPlayerState, iIsReady );
       
   869 
       
   870     if ( result == CUPnPValueStateMachine::EHandle )
       
   871         {
       
   872         iValueStateMachine->ValueL( aProperty );
       
   873         }
       
   874     else if ( result == CUPnPValueStateMachine::EHandleStatic )
       
   875         {
       
   876         CUPnPValueStateMachine::ValueStatic( aProperty, *iObs );
       
   877         }
       
   878     else if ( result == CUPnPValueStateMachine::EErrorNotReady )
       
   879         {
       
   880         iObs->HandleProperty( aProperty,
       
   881             0, KErrNotReady );
       
   882         }
       
   883     else if ( result == CUPnPValueStateMachine::EErrorNotSupported )
       
   884         {
       
   885         iObs->HandleProperty( aProperty,
       
   886             0, KErrNotSupported );
       
   887         }
       
   888     else if ( result == CUPnPValueStateMachine::EIgnore )
       
   889         {
       
   890         // do nothing
       
   891         }
       
   892     else 
       
   893         {
       
   894         __PANICD( __FILE__, __LINE__ );
       
   895         }
       
   896       
       
   897     }
       
   898 
       
   899 // --------------------------------------------------------------------------
       
   900 // CUPnPMusicPlayer::SubPlayerNamesL
       
   901 // Gets a list of sub players (async).
       
   902 // --------------------------------------------------------------------------
       
   903 //
       
   904 void CUPnPMusicPlayer::SubPlayerNamesL()
       
   905     {
       
   906     __LOG1( "CUPnPMusicPlayer::SubPlayerNamesL [%d]", this );
       
   907    
       
   908     // Get media renderers from renderer selector
       
   909     iSingleton->GetRendererNamesL( *this );
       
   910     }
       
   911 
       
   912 // --------------------------------------------------------------------------
       
   913 // CUPnPMusicPlayer::SelectSubPlayerL
       
   914 // Select a sub player.
       
   915 // --------------------------------------------------------------------------
       
   916 //  
       
   917 void CUPnPMusicPlayer::SelectSubPlayerL( TInt aIndex )
       
   918     {
       
   919     __LOG1( "CUPnPMusicPlayer::SelectSubPlayerL [%d]", this );
       
   920             
       
   921     // this method can only be called in uninitialized state
       
   922     __ASSERTD( iPlayerState == EStateUninitialised ||
       
   923     aIndex == iSelectedRendererIndex, __FILE__, __LINE__ );
       
   924  
       
   925     // Select media renderer. Ignore if already selected.
       
   926     if ( iSelectedRendererIndex != aIndex )
       
   927         {
       
   928         iSelectedRendererIndex = aIndex;
       
   929         CUpnpAVDevice* tempDev = CUpnpAVDevice::NewL( 
       
   930             *iSingleton->SelectRendererByIndexL( aIndex ) );
       
   931         delete iSelectedRenderer;
       
   932         iSelectedRenderer = tempDev;
       
   933         }
       
   934     }
       
   935 
       
   936 // --------------------------------------------------------------------------
       
   937 // CUPnPMusicPlayer::SubPlayerName
       
   938 // Returns current sub player name
       
   939 // --------------------------------------------------------------------------
       
   940 // 
       
   941 const TDesC& CUPnPMusicPlayer::SubPlayerName()
       
   942     {
       
   943     __LOG1( "CUPnPMusicPlayer::SubPlayerName [%d]", this );
       
   944     if ( iSelectedRenderer )
       
   945         {
       
   946         iSelectedRendererName.Copy(
       
   947             iSelectedRenderer->FriendlyName() );
       
   948         }
       
   949     else if ( iSingleton->DefaultDevice() )
       
   950         {
       
   951         iSelectedRendererName.Copy(
       
   952             iSingleton->DefaultDevice()->FriendlyName() );
       
   953         }
       
   954     else
       
   955         {
       
   956         iSelectedRendererName.Copy( KNullDesC );
       
   957         }
       
   958     return iSelectedRendererName;
       
   959     }
       
   960 
       
   961 // --------------------------------------------------------------------------
       
   962 // CUPnPMusicPlayer::SubPlayerIndex
       
   963 // Return current sub player index.
       
   964 // --------------------------------------------------------------------------
       
   965 //    
       
   966 TInt CUPnPMusicPlayer::SubPlayerIndex() const
       
   967     {
       
   968     __LOG1( "CUPnPMusicPlayer::SubPlayerIndex [%d]", this );
       
   969 
       
   970     // Get current sub player index
       
   971     return iSelectedRendererIndex;
       
   972     }
       
   973 
       
   974 // --------------------------------------------------------------------------
       
   975 // CUPnPMusicPlayer::MediaL
       
   976 // Extended properties of the current file (async).
       
   977 // --------------------------------------------------------------------------
       
   978 //
       
   979 void CUPnPMusicPlayer::MediaL( const TArray<TMPXAttribute>& aAttrs )
       
   980     {
       
   981     __LOG2( "CUPnPMusicPlayer::MediaL in state %S [%d]",
       
   982         State( iPlayerState ), this );
       
   983 
       
   984     // Get media if track is initialised
       
   985     if( iTrack )
       
   986         {
       
   987         iTrack->GetMetaDataL( aAttrs, *iObs );
       
   988         }
       
   989     else
       
   990         {
       
   991         __LOG( "CUPnPMusicPlayer::MediaL - Wrong state!" );
       
   992         User::Leave( KErrNotReady );
       
   993         }
       
   994     }
       
   995 
       
   996 // --------------------------------------------------------------------------
       
   997 // CUPnPMusicPlayer::CancelRequest
       
   998 // Cancel outstanding request.
       
   999 // --------------------------------------------------------------------------
       
  1000 //   
       
  1001 void CUPnPMusicPlayer::CancelRequest()
       
  1002     {
       
  1003     __LOG2( "CUPnPMusicPlayer::CancelRequest in state %S [%d]",
       
  1004         State( iPlayerState ), this );
       
  1005 
       
  1006     // If cancel is called during initialise
       
  1007     if( iPlayerState == EStateInitializing || 
       
  1008         iPlayerState == EStatePreInitializing || 
       
  1009         iPlayerState == EStateActiveForceInitialise ||
       
  1010         iPlayerState == EStateActive )
       
  1011         {
       
  1012         // Stop rendering session -> SetURI operation will be cancelled
       
  1013         UninitialiseTrack( EStateNone );
       
  1014         iPlayerState = EStateUninitialised;
       
  1015         }
       
  1016     else if( iPlayerState == EStateUninitialising )
       
  1017         {
       
  1018         // Ignore. Do not call state machines.
       
  1019         return;
       
  1020         }
       
  1021 
       
  1022     if ( iSingleton != 0 )
       
  1023         {
       
  1024         iSingleton->CancelGetRendererNames();
       
  1025         }
       
  1026     if ( iPlaybackStateMachine )
       
  1027         {
       
  1028         iPlaybackStateMachine->Cancel();
       
  1029         }
       
  1030     if ( iValueStateMachine )
       
  1031         {
       
  1032         iValueStateMachine->Cancel();
       
  1033         }
       
  1034     }
       
  1035 
       
  1036 // --------------------------------------------------------------------------
       
  1037 // Methods of MUPnPAVRenderingSessionObserver
       
  1038 // --------------------------------------------------------------------------
       
  1039 
       
  1040 // --------------------------------------------------------------------------
       
  1041 // CUPnPMusicPlayer::VolumeResult
       
  1042 // Response for get/set volume property commands.
       
  1043 // --------------------------------------------------------------------------
       
  1044 //
       
  1045 void CUPnPMusicPlayer::VolumeResult( TInt aError, TInt aVolumeLevel,
       
  1046     TBool aActionResponse )
       
  1047     {
       
  1048     __LOG2( "CUPnPMusicPlayer::VolumeResult in state %S [%d]",
       
  1049         State( iPlayerState ), this );
       
  1050 
       
  1051     if( iValueStateMachine )
       
  1052         {
       
  1053         iValueStateMachine->VolumeResult( aError, aVolumeLevel,
       
  1054             aActionResponse );
       
  1055         }
       
  1056     }
       
  1057 
       
  1058 // --------------------------------------------------------------------------
       
  1059 // CUPnPMusicPlayer::MuteResult
       
  1060 // Response for get/set mute property commands.
       
  1061 // --------------------------------------------------------------------------
       
  1062 //
       
  1063 void CUPnPMusicPlayer::MuteResult( TInt aError, TBool aMute,
       
  1064     TBool aActionResponse )
       
  1065     {
       
  1066     __LOG2( "CUPnPMusicPlayer::MuteResult in state %S [%d]",
       
  1067         State( iPlayerState ), this );
       
  1068 
       
  1069     if( iValueStateMachine )
       
  1070         {
       
  1071         iValueStateMachine->MuteResult( aError, aMute, aActionResponse );
       
  1072         }
       
  1073     }
       
  1074 
       
  1075 // --------------------------------------------------------------------------
       
  1076 // CUPnPMusicPlayer::InteractOperationComplete
       
  1077 // Response for interaction operation (play, stop, etc.).
       
  1078 // --------------------------------------------------------------------------
       
  1079 //
       
  1080 void CUPnPMusicPlayer::InteractOperationComplete( TInt aErrorCode, 
       
  1081     TUPnPAVInteractOperation aOperation )
       
  1082     {
       
  1083     __LOG3( "CUPnPMusicPlayer::InteractOp.Comp(%d) in state %S [%d]",
       
  1084         aOperation, State( iPlayerState ), this );
       
  1085 
       
  1086     if( iPlayerState == EStateActive )
       
  1087         {
       
  1088         if( iPlaybackStateMachine )
       
  1089             {
       
  1090             iPlaybackStateMachine->InteractOperationComplete( aErrorCode,
       
  1091                 aOperation );
       
  1092             }
       
  1093         }
       
  1094     }
       
  1095 
       
  1096 // --------------------------------------------------------------------------
       
  1097 // CUPnPMusicPlayer::PositionInfoResult
       
  1098 // Response for position/duration requests.
       
  1099 // --------------------------------------------------------------------------
       
  1100 //
       
  1101 void CUPnPMusicPlayer::PositionInfoResult( TInt aStatus,
       
  1102     const TDesC8& aTrackPosition, const TDesC8& aTrackLength )
       
  1103     {
       
  1104     __LOG2( "CUPnPMusicPlayer::PositionInfoResult in state %S [%d]",
       
  1105         State( iPlayerState ), this );
       
  1106     
       
  1107     if( iValueStateMachine )
       
  1108         {
       
  1109         iValueStateMachine->PositionInfoResult( aStatus, aTrackPosition, 
       
  1110             aTrackLength );
       
  1111         }
       
  1112     }
       
  1113 
       
  1114 // --------------------------------------------------------------------------
       
  1115 // CUPnPMusicPlayer::SetURIResult
       
  1116 // Response for SetURI.
       
  1117 // --------------------------------------------------------------------------
       
  1118 //  
       
  1119 void CUPnPMusicPlayer::SetURIResult( TInt aError )
       
  1120     {
       
  1121     __LOG3( "CUPnPMusicPlayer::SetURIResult in state %S err=%d [%d]",
       
  1122         State( iPlayerState ), aError, this );
       
  1123 
       
  1124     if( iPlayerState == EStateInitializing )
       
  1125         {
       
  1126         // "Normal" response for SetURI
       
  1127         TInt duration(0);
       
  1128         if( aError == KErrNone )
       
  1129             {
       
  1130             // Set player state to active
       
  1131             ChangeState( EStateActive );
       
  1132             TRAP_IGNORE( iAudioPolicy->PlayL() );
       
  1133             duration = iTrack->TrackDuration();
       
  1134             }
       
  1135         else
       
  1136             {
       
  1137             UninitialiseTrack();
       
  1138             }
       
  1139         // if aError is KErrGeneral, the music player doesn't skip to
       
  1140         //the next song .  translate to KErrCorrupt.
       
  1141         if( aError == KErrGeneral)
       
  1142             {
       
  1143             aError = KErrCorrupt;
       
  1144             }
       
  1145         else
       
  1146             {
       
  1147             aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
       
  1148             }
       
  1149         iObs->HandlePluginEvent( 
       
  1150             MMPXPlaybackPluginObserver::EPInitialised, duration, aError );
       
  1151         if ( iPlayerState == EStateActive )
       
  1152             {
       
  1153             TRAP_IGNORE(
       
  1154                 if( iTrack->IsRemote() )
       
  1155                     {
       
  1156                     iTrack->SendMediaChangedEventL( *iObs );
       
  1157                     }
       
  1158                 );
       
  1159             }
       
  1160         }
       
  1161     else if( iPlayerState == EStateActiveForceInitialise )
       
  1162         {
       
  1163         // Response for preinitialise that is failed because of
       
  1164         // used device does not support SetNextUri functionality.
       
  1165         if( aError == KErrNone )
       
  1166             {            
       
  1167             __LOG( "SetURIResult,ActiveForceInitialise->Play" );
       
  1168             // Set player state to active
       
  1169             iPlayerState = EStateActive;
       
  1170             TRAP_IGNORE( iAudioPolicy->PlayL() );
       
  1171                             
       
  1172             // Play 
       
  1173             TRAPD( error, CommandL( EPbCmdPlay, TInt(0) ) );
       
  1174             if ( error != KErrNone )
       
  1175                 {
       
  1176                 UninitialiseTrack();
       
  1177                 // Send play event with error to user. Note play event
       
  1178                 // because we are actually performing play command.
       
  1179                 error = TUpnpPluginsErrorTranslation::ErrorTranslate( error );
       
  1180                 iObs->HandlePluginEvent(
       
  1181                     MMPXPlaybackPluginObserver::EPPlaying,
       
  1182                     0, error );
       
  1183                 // Send event that device is not available.
       
  1184                 iObs->HandlePluginEvent(
       
  1185                     MMPXPlaybackPluginObserver::EPPlayerUnavailable,
       
  1186                     0, KErrNotFound );
       
  1187                 }
       
  1188             }
       
  1189         else
       
  1190             {
       
  1191             UninitialiseTrack();
       
  1192             // Send play event with error to user. Note play event
       
  1193             // because weare actually performing play command.
       
  1194             aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
       
  1195             iObs->HandlePluginEvent(
       
  1196                 MMPXPlaybackPluginObserver::EPPlaying,
       
  1197                 0, aError );
       
  1198             }
       
  1199         }
       
  1200     else if( iPlayerState == EStatePauseInActiveForceInitialise )
       
  1201         {
       
  1202         // This case happens when active plugin is paused and user 
       
  1203         // skips to the next track from UI.
       
  1204         __LOG( "SetUriResult during EStatePauseInActiveForceInitialise" );
       
  1205 
       
  1206         iPlayerState = EStateActive;
       
  1207         if( aError == KErrNone )
       
  1208             {
       
  1209             // Pause
       
  1210             TRAPD( error, CommandL( EPbCmdPause, TInt(0) ) );
       
  1211             if ( error != KErrNone )
       
  1212                 {
       
  1213                 UninitialiseTrack();
       
  1214                 // Send pause event with error to user. Note pause event
       
  1215                 // because we are actually performing pause command.
       
  1216                 error = TUpnpPluginsErrorTranslation::ErrorTranslate( error );
       
  1217                 iObs->HandlePluginEvent(
       
  1218                     MMPXPlaybackPluginObserver::EPPaused,
       
  1219                     0, error );
       
  1220                 }
       
  1221             }
       
  1222         else
       
  1223             {
       
  1224             UninitialiseTrack();
       
  1225             // Send pause event with error to user. Note pause event
       
  1226             // because we are actually performing pause command.
       
  1227             aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
       
  1228             iObs->HandlePluginEvent(
       
  1229                 MMPXPlaybackPluginObserver::EPPaused, 0, aError );
       
  1230             }
       
  1231         }
       
  1232     else // Covers also if Cancel request is called during SetURI
       
  1233         {
       
  1234         __LOG( "CUPnPMusicPlayer::SetURIResult - Unknown state " );
       
  1235         }
       
  1236     }
       
  1237     
       
  1238 // --------------------------------------------------------------------------
       
  1239 // CUPnPMusicPlayer::SetNextURIResult
       
  1240 // Response for SetNextURI.
       
  1241 // --------------------------------------------------------------------------
       
  1242 //  
       
  1243 void CUPnPMusicPlayer::SetNextURIResult( TInt aError )
       
  1244     {
       
  1245     __LOG2( "CUPnPMusicPlayer::SetNextURIResult err=%d [%d]",
       
  1246         aError, this );
       
  1247 
       
  1248     aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
       
  1249     if( iPlayerState == EStatePreInitializing )
       
  1250         {
       
  1251         TInt duration(0);
       
  1252         // Check if any error during SetNextURI call
       
  1253         if( aError == KErrNone )
       
  1254             {
       
  1255             // Set palyer state to preinitialized
       
  1256             ChangeState( EStatePreInitialized );
       
  1257             duration = iTrack->TrackDuration();
       
  1258             }
       
  1259         else 
       
  1260             {
       
  1261             // Used renderer does not support SetNextURI feature. 
       
  1262             // Initialise track by SetURI after play is called.
       
  1263             ChangeState( EStateWaiting );
       
  1264             }
       
  1265         iObs->HandlePluginEvent( 
       
  1266             MMPXPlaybackPluginObserver::EPInitialised, duration, aError );
       
  1267         if ( iPlayerState == EStatePreInitialized )
       
  1268             {
       
  1269             TRAP_IGNORE(
       
  1270                 if( iTrack->IsRemote() )
       
  1271                     {
       
  1272                     iTrack->SendMediaChangedEventL( *iObs );
       
  1273                     }
       
  1274                 );
       
  1275             }
       
  1276         }
       
  1277     else
       
  1278         {
       
  1279         __LOG( "CUPnPMusicPlayer::SetNextURIResult - Wrong state! " );
       
  1280         __PANICD( __FILE__, __LINE__ );
       
  1281         }
       
  1282     }
       
  1283 
       
  1284 // --------------------------------------------------------------------------
       
  1285 // CUPnPMusicPlayer::MediaRendererDisappeared
       
  1286 // Indication in case of renderer disappear
       
  1287 // --------------------------------------------------------------------------
       
  1288 // 
       
  1289 void CUPnPMusicPlayer::MediaRendererDisappeared( 
       
  1290     TUPnPDeviceDisconnectedReason aReason )
       
  1291     {
       
  1292     __LOG1( "CUPnPMusicPlayer::MediaRendererDisappeared [%d]",
       
  1293         this );
       
  1294     
       
  1295     if ( aReason == MUPnPAVSessionObserverBase::EWLANLost )
       
  1296         {
       
  1297         if( iTrack )
       
  1298             {
       
  1299             if ( iTrack->IsRemote() )
       
  1300                 {
       
  1301                 __LOG( "CUPnPMusicPlayer::MediaRendererDisappeared - \
       
  1302                 WLAN disappeared while playing a REMOTE track " );
       
  1303                 // WLAN disappeared while playing a REMOTE track
       
  1304                 // stop rendering session and inform player             
       
  1305                 // Fixes ESLX-7KQERV
       
  1306                 CancelRequest();
       
  1307                 UninitialiseTrack( EStateError );
       
  1308                 iObs->HandlePluginEvent(
       
  1309                     MMPXPlaybackPluginObserver::EPPlayerUnavailable,
       
  1310                     0, KErrDisconnected );
       
  1311                 }
       
  1312             else
       
  1313                 {
       
  1314                 __LOG( "CUPnPMusicPlayer::MediaRendererDisappeared - \
       
  1315                 WLAN disappeared while playing a LOCAL track " );
       
  1316                 // WLAN disappeared while playing a LOCAL track
       
  1317                 // signal not available.
       
  1318                 UninitialiseTrack( EStateError );
       
  1319                 iObs->HandlePluginEvent(
       
  1320                     MMPXPlaybackPluginObserver::EPPlayerUnavailable,
       
  1321                     0, KErrNone );
       
  1322                 }
       
  1323             }
       
  1324         else // Track does not exist -> state is already uninitialised
       
  1325             {
       
  1326             iObs->HandlePluginEvent(
       
  1327                 MMPXPlaybackPluginObserver::EPPlayerUnavailable,
       
  1328                 0, KErrNone );
       
  1329             }
       
  1330         }
       
  1331     else
       
  1332         {
       
  1333         // renderer disappeared
       
  1334         UninitialiseTrack( EStateUninitialised );
       
  1335         iObs->HandlePluginEvent(
       
  1336             MMPXPlaybackPluginObserver::EPPlayerUnavailable,
       
  1337             0, KErrNotFound );
       
  1338         }
       
  1339     }
       
  1340 
       
  1341 // --------------------------------------------------------------------------
       
  1342 // CUPnPMusicPlayer::ReserveLocalMSServicesCompleted
       
  1343 // --------------------------------------------------------------------------
       
  1344 // 
       
  1345 void CUPnPMusicPlayer::ReserveLocalMSServicesCompleted( TInt /*aError*/ )
       
  1346     {
       
  1347     __LOG1( "CUPnPMusicPlayer::ReserveMSCompleted!? [%d]", this );
       
  1348     // Implementation no needed.
       
  1349     }
       
  1350 
       
  1351 // --------------------------------------------------------------------------
       
  1352 // CUPnPMusicPlayer::HandleSubPlayerNames
       
  1353 // Response for GetSubplayerNames request.
       
  1354 // --------------------------------------------------------------------------
       
  1355 // 
       
  1356 void CUPnPMusicPlayer::HandleSubPlayerNames( const MDesCArray* aSubPlayers, 
       
  1357     TBool aComplete, TInt aError )
       
  1358     {
       
  1359     __LOG2( "CUPnPMusicPlayer::HandleSubPlayerNames in state %S [%d]",
       
  1360         State( iPlayerState ), this );
       
  1361     
       
  1362     aError = TUpnpPluginsErrorTranslation::ErrorTranslate( aError );
       
  1363     // Return subplayer names
       
  1364     iObs->HandleSubPlayerNames( KMusicPlayerUid, aSubPlayers,
       
  1365         aComplete, aError );
       
  1366     }
       
  1367 
       
  1368 // --------------------------------------------------------------------------
       
  1369 // CUPnPMusicPlayer::RendererListChanged
       
  1370 // Call back if reanderer list has changed.
       
  1371 // --------------------------------------------------------------------------
       
  1372 // 
       
  1373 void CUPnPMusicPlayer::RendererListChanged()
       
  1374     {
       
  1375     __LOG2( "CUPnPMusicPlayer::RendererListChanged in state %S [%d]",
       
  1376         State( iPlayerState ), this );
       
  1377     
       
  1378     // Create EPSubPlayersChanged event
       
  1379     iObs->HandlePluginEvent(
       
  1380         MMPXPlaybackPluginObserver::EPSubPlayersChanged,
       
  1381         KErrNone, KErrNone );
       
  1382     }
       
  1383 
       
  1384 
       
  1385 // --------------------------------------------------------------------------
       
  1386 // CUPnPMusicPlayer::AudioConflict
       
  1387 // --------------------------------------------------------------------------
       
  1388 //
       
  1389 void CUPnPMusicPlayer::AudioConflict( TInt /*aError*/ )
       
  1390     {
       
  1391 
       
  1392     // stop playing
       
  1393     TRAP_IGNORE( iPlaybackStateMachine->SilentStopL() );
       
  1394 
       
  1395     // notify framework        
       
  1396     iObs->HandlePluginEvent(
       
  1397         MMPXPlaybackPluginObserver::EPStopped,
       
  1398         0, KErrNone );
       
  1399     }
       
  1400 
       
  1401 // --------------------------------------------------------------------------
       
  1402 // CUPnPMusicPlayer::ChangeState
       
  1403 // --------------------------------------------------------------------------
       
  1404 //
       
  1405 void CUPnPMusicPlayer::ChangeState( TPlayerState aNewState )
       
  1406     {   
       
  1407     __LOG3( "CUPnPMusicPlayer: STATE %S -> %S [%d]",
       
  1408         State( iPlayerState ), State( aNewState ), this );
       
  1409 
       
  1410     iPlayerState = aNewState;
       
  1411     }
       
  1412 
       
  1413 
       
  1414 // --------------------------------------------------------------------------
       
  1415 // CUPnPMusicPlayer::State
       
  1416 // --------------------------------------------------------------------------
       
  1417 //
       
  1418 const TDesC* CUPnPMusicPlayer::State( TPlayerState aState ) const
       
  1419     {
       
  1420     switch( aState )
       
  1421         {
       
  1422         case EStateUninitialised:
       
  1423             {
       
  1424             return &KStateUninitialized;
       
  1425             }
       
  1426         case EStateInitializing:
       
  1427             {
       
  1428             return &KStateInitializing;
       
  1429             }
       
  1430         case EStateUninitialising:
       
  1431             {
       
  1432             return &KStateUninitialising;
       
  1433             }
       
  1434          case EStateActive:
       
  1435             {
       
  1436             return &KStateActive;
       
  1437             }
       
  1438          case EStatePreInitializing:
       
  1439             {
       
  1440             return &KStatePreInitializing;
       
  1441             }
       
  1442          case EStatePreInitialized:
       
  1443             {
       
  1444             return &KStatePreInitialized;
       
  1445             }
       
  1446         case EStateWaiting:
       
  1447             {
       
  1448             return &KStateWaiting;
       
  1449             }
       
  1450         case EStateActiveForceInitialise:
       
  1451             {
       
  1452             return &KStateActiveForceInit;
       
  1453             }
       
  1454         case EStateError:
       
  1455             {
       
  1456             return &KStateError;
       
  1457             }
       
  1458         default:
       
  1459             {
       
  1460             return &KStateUnknown;
       
  1461             }
       
  1462         }
       
  1463     }
       
  1464 
       
  1465  
       
  1466