upnpmpxplugins/upnpplaybackplugins/src/upnpmusicdownloadproxy.cpp
changeset 0 7f85d04be362
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpmpxplugins/upnpplaybackplugins/src/upnpmusicdownloadproxy.cpp	Thu Dec 17 08:52:00 2009 +0200
@@ -0,0 +1,535 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:      Proxy for downloading upnp files and playing locally
+*
+*/
+
+
+
+
+
+
+// INCLUDES
+#include <upnpitem.h>
+#include "upnpitemutility.h" // for ResourceFromItemL
+#include "upnpavcontroller.h"
+#include "upnpmusicdownloadproxy.h"
+#include "upnpsingleton.h"
+#include "upnptrack.h"
+
+_LIT( KComponentLogfile, "musicplugins.txt");
+#include "upnplog.h"
+
+#include "upnppluginserrortranslation.h"
+
+// CONSTANTS
+// ** a message to music player to complete an immediate exit
+const TInt KMusicPluginMessageExit = 3001;
+const TUid KLocalPlayerDefinitionUid = { 0x101FFC06 };
+
+// ======== MEMBER FUNCTIONS ========
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::NewL
+// 1st phase constructor.
+// --------------------------------------------------------------------------
+//
+CUPnPMusicDownloadProxy* CUPnPMusicDownloadProxy::NewL( 
+    MMPXPlaybackPluginObserver& aObs )
+    {
+    CUPnPMusicDownloadProxy* p = new ( ELeave )
+        CUPnPMusicDownloadProxy( aObs );
+    __LOG1( "DownloadProxy: NewL this=%d", p );
+    CleanupStack::PushL( p );
+    p->ConstructL();
+    CleanupStack::Pop();
+    return p;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::CUPnPMusicDownloadProxy
+// Default constructor.
+// --------------------------------------------------------------------------
+// 
+CUPnPMusicDownloadProxy::CUPnPMusicDownloadProxy(
+    MMPXPlaybackPluginObserver& aObs )
+    : iProxyState( EStateUninitialised )
+    {
+    iObs = &aObs;
+    iLocalPlayer = NULL;
+    iSingleton = NULL;
+    iTrack = NULL;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::ConstructL
+// 1st phase constructor.
+// --------------------------------------------------------------------------
+//  
+void CUPnPMusicDownloadProxy::ConstructL()
+    {
+    __LOG( "DownloadProxy: ConstructL" );
+
+    // Construct the underlying local plugin
+    iLocalPlayer = CMPXPlaybackPlugin::NewL(
+        KLocalPlayerDefinitionUid );
+
+    // Create handle to singleton
+    iSingleton = CUPnPSingleton::GetInstanceL();
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::~CUPnPMusicDownloadProxy
+// Destructor.
+// --------------------------------------------------------------------------
+//
+CUPnPMusicDownloadProxy::~CUPnPMusicDownloadProxy()
+    {
+    __LOG1( "DownloadProxy: destructor [%d]",
+       this );
+    Cleanup();
+
+    // Free memory of owned members
+    delete iLocalPlayer;
+    CUPnPSingleton::LoseInstance( iSingleton );
+    }
+    
+
+// --------------------------------------------------------------------------
+// Methods from CMPXPlaybackPlugin
+// --------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::InitialiseL
+// --------------------------------------------------------------------------
+//  
+void CUPnPMusicDownloadProxy::InitialiseL( const TDesC& aSong )
+    {
+    __LOG2( "DownloadProxy::InitialiseL(%S) [%d]",
+        &aSong, this );
+
+    __ASSERTD( iProxyState == EStateUninitialised,__FILE__, __LINE__ );
+
+    iProxyState = EStatePreparing;
+
+    // Create local track object to resolving URI
+    delete iTrack;
+    iTrack = 0;
+    iTrack = CUPnPTrack::NewL( iSingleton->AVC() );
+    iTrack->ResolveURIL( aSong, *this, CUPnPTrack::EDirectionLocal );
+    iProxyState = EStateDownloading;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::InitialiseL
+// --------------------------------------------------------------------------
+//  
+void CUPnPMusicDownloadProxy::InitialiseL( RFile& /*aSong*/ )
+    {
+    // Not used. Only remote file is supported
+    __PANICD( __FILE__, __LINE__ );
+    User::Leave( KErrNotSupported );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::HandleMetaData
+// from MUPnPTrackMetaDataObserver
+// --------------------------------------------------------------------------
+// 
+void CUPnPMusicDownloadProxy::ResolveURIComplete( TInt aError )
+    {
+    __LOG1( "DownloadProxy::ResolveURIComplete [%d]", this );
+    __ASSERTD( iProxyState == EStateDownloading,__FILE__, __LINE__ );
+
+    if ( aError == KErrNone )
+        {                        
+        TRAPD( initerror, iLocalPlayer->InitialiseL( 
+            iTrack->FilePath() ) );
+
+        if ( initerror != KErrNone )
+            {
+            __LOG1( "DownloadProxy:local player init leaves: %d",
+                initerror );
+            Cleanup();
+            iProxyState = EStateUninitialised;
+            //translate error
+            initerror = TUpnpPluginsErrorTranslation::ErrorTranslate( 
+                initerror );
+            iObs->HandlePluginEvent( 
+            MMPXPlaybackPluginObserver::EPInitialised, 0, initerror );
+            }
+        else
+            {
+            iProxyState = EStateInitialisingLocally;
+            }
+        }
+    else
+        {
+        __LOG1("DownloadProxy::ResolveURIComplete: error %d",
+            aError );
+        Cleanup();
+        iProxyState = EStateUninitialised;
+        aError = TUpnpPluginsErrorTranslation::ErrorTranslate( 
+                aError );
+        iObs->HandlePluginEvent( 
+            MMPXPlaybackPluginObserver::EPInitialised,
+            0, aError );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::CommandL
+// --------------------------------------------------------------------------
+//  
+void CUPnPMusicDownloadProxy::CommandL( TMPXPlaybackCommand aCmd, 
+    TInt aData )
+    {
+    __LOG2( "DownloadProxy::CommandL(%d) [%d]", aCmd, this );
+    
+    if( iProxyState == EStateActive )
+        {
+        // ACTIVE state: all commands are forwarded to local plugin
+        __LOG( "DownloadProxy: command in active state" );
+        iLocalPlayer->CommandL( aCmd, aData );
+        }
+    else if ( iProxyState == EStatePreparing && aCmd == EPbCmdClose )
+        {
+        __LOG( "DownloadProxy: Close during prepare" );
+        Cleanup();
+        iProxyState = EStateUninitialised;
+        iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPClosed,
+            0, KErrNone );
+        }
+    else if( iProxyState == EStateDownloading && aCmd == EPbCmdClose )
+        {
+        __LOG( "DownloadProxy: Close during download" );
+        Cleanup(); // this will cancel ongoing copy
+        iProxyState = EStateUninitialised;
+        iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPClosed,
+            0, KErrNone );
+        }
+    else if( iProxyState == EStateInitialisingLocally && 
+        aCmd == EPbCmdClose )
+        {
+        __LOG( "DownloadProxy: Close when initialising locally" );
+        iLocalPlayer->CommandL( aCmd, aData );
+        }
+    else if( iProxyState == EStateUninitialised && aCmd == EPbCmdClose )
+        {
+        __LOG( "DownloadProxy: Close when uninitialized" );
+        iObs->HandlePluginEvent( MMPXPlaybackPluginObserver::EPClosed,
+            0, KErrNone );
+        }
+    else if( ( iProxyState == EStatePreparing ||
+        iProxyState == EStateDownloading ||
+        iProxyState == EStateInitialisingLocally ||
+        iProxyState == EStateUninitialised ) && aCmd == EPbCmdStop )
+        {
+        __LOG( "DownloadProxy: Stop during any state" );
+        iLocalPlayer->CommandL( aCmd, aData );
+        }
+    else // Not initialized
+        {
+        __LOG1( "DownloadProxy: Command not supported in this state: %d",
+            iProxyState );
+        User::Leave( KErrNotReady );    
+        }
+
+    // check for messages from upnp framework (aData param)
+    if ( aCmd == EPbCmdClose &&
+        aData == KMusicPluginMessageExit )
+        {
+        __LOG( "CommandL(Close, exit) -> cleanup and terminate" );
+
+        // cancel things that are ongoing
+        Cleanup();
+        iLocalPlayer->CancelRequest();
+        iProxyState = EStateUninitialised;
+
+        // Create event to user
+        
+        iObs->HandlePluginEvent(
+            MMPXPlaybackPluginObserver::EPPlayerUnavailable,
+            0, KErrDisconnected);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::SetL
+// --------------------------------------------------------------------------
+//  
+void CUPnPMusicDownloadProxy::SetL( TMPXPlaybackProperty aProperty,
+    TInt aValue )
+    {
+    __LOG1( "DownloadProxy::SetL [%d]", this );
+    __LOG1( "Property=%d", (TInt)aProperty );
+    iLocalPlayer->SetL( aProperty, aValue );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::ValueL
+// --------------------------------------------------------------------------
+//  
+void CUPnPMusicDownloadProxy::ValueL( TMPXPlaybackProperty aProperty ) const
+    {
+    __LOG1( "DownloadProxy::ValueL [%d]", this );
+    iLocalPlayer->ValueL( aProperty );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::SubPlayerNamesL
+// --------------------------------------------------------------------------
+//  
+void CUPnPMusicDownloadProxy::SubPlayerNamesL()
+    {
+    iLocalPlayer->SubPlayerNamesL();
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::SelectSubPlayerL
+// --------------------------------------------------------------------------
+//   
+void CUPnPMusicDownloadProxy::SelectSubPlayerL( TInt aIndex )
+    {
+    iLocalPlayer->SelectSubPlayerL( aIndex );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::SubPlayerName
+// Returns current sub player name
+// --------------------------------------------------------------------------
+// 
+const TDesC& CUPnPMusicDownloadProxy::SubPlayerName()
+    {
+    return iLocalPlayer->SubPlayerName();
+    }
+    
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::SubPlayerIndex
+// --------------------------------------------------------------------------
+//  
+TInt CUPnPMusicDownloadProxy::SubPlayerIndex() const
+    {
+    return iLocalPlayer->SubPlayerIndex();
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::MediaL
+// --------------------------------------------------------------------------
+//
+void CUPnPMusicDownloadProxy::MediaL( const TArray<TMPXAttribute>& aAttrs )
+    {
+    // Get metadata from media server
+    if( iTrack )
+        {
+        __LOG1( "DownloadProxy: Get metadata [%d]", this );
+        iTrack->GetMetaDataL( aAttrs, *iObs );
+        }
+    else
+        {
+        __LOG( "DownloadProxy: Get metadata - no track!" );
+        User::Leave( KErrNotReady );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::CancelRequest
+// --------------------------------------------------------------------------
+//
+void CUPnPMusicDownloadProxy::CancelRequest()
+    {
+    __LOG( "CUPnPMusicDownloadProxy::CancelRequest" );
+    if( iProxyState == EStateDownloading )
+        {
+        Cleanup(); // this will cancel ongoing copy
+        iProxyState = EStateUninitialised;
+        // Send "downloading cancelled" event to the user 
+        iObs->HandlePluginEvent( 
+            MMPXPlaybackPluginObserver::EPDownloadingCanceled,
+            0, KErrGeneral );
+        }
+    iLocalPlayer->CancelRequest();
+    }
+
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::SetObserver
+// --------------------------------------------------------------------------
+//
+void CUPnPMusicDownloadProxy::SetObserver(MMPXPlaybackPluginObserver& aObs)
+    {
+    CMPXPlaybackPlugin::SetObserver( aObs );
+    
+    iLocalPlayer->SetObserver( *this ); 
+    }
+
+// --------------------------------------------------------------------------
+// Methods from MMPXPlaybackPluginObserver
+// --------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::HandlePluginEvent
+// --------------------------------------------------------------------------
+// 
+void CUPnPMusicDownloadProxy::HandlePluginEvent( TEvent aEvent,
+    TInt aData, TInt aError )
+    {
+    __LOG1( "DownloadProxy::HandlePluginEvent [%d]", this );
+
+    switch( aEvent )
+        {
+        case EPInitialised:
+            {
+            __ASSERTD( iProxyState == EStateInitialisingLocally,__FILE__, 
+                __LINE__ );
+            __LOG1( "DownloadProxy: initialised event, err=%d",
+                aError );
+
+            // Proxied local plugin initialized
+            if ( aError == KErrNone )
+                {
+                iProxyState = EStateActive;
+             
+                iObs->HandlePluginEvent( aEvent, aData, aError );
+                }
+            else
+                {
+                iProxyState = EStateClosing;
+                TRAP_IGNORE (
+                    iLocalPlayer->CommandL( EPbCmdClose, 0 ) );
+                }
+            
+            if ( iProxyState == EStateActive )
+                {
+                TRAP_IGNORE(
+                    iTrack->SendMediaChangedEventL( *iObs );
+                    );
+                }
+            break;
+            }
+        case EPPlaying:             // fall through
+        case EPPlayComplete:        // fall through
+        case EPPaused:              // fall through
+        case EPStopped:             // fall through
+        case EPDownloadStarted:     // fall through
+        case EPDownloadingComplete: // fall through
+        case EPSubPlayersChanged:   // fall through
+        case EPVolumeChanged:       // fall through
+        case EPSetComplete:
+            {
+            __LOG2( "DownloadProxy plugin event=%d err=%d",
+                (TInt)aEvent, aError );
+
+            // Just forward event to the user.
+            aError = TUpnpPluginsErrorTranslation::ErrorTranslate( 
+                    aError );
+            iObs->HandlePluginEvent( aEvent, aData, aError );
+            break;
+            }
+        case EPClosed:
+            {
+            __LOG( "DownloadProxy: closed event" );
+
+            // a Stop command has changed. It will send back a Stopped event 
+            // and then a Closed event. Following Pause command will not be 
+            // accepted in Uninitialized state and CommandL() will leave. 
+            // This change in MPX was necessary to let engine know the file 
+            // was closed. One additional aData parameter is passed in 
+            // iObs->HandlePluginEvent(MMPXPlaybackPluginObserver::EPClosed, 
+            //    EPbCmdStop, KErrNone); to know the difference between a 
+            // real Close and a Stop/Close. When this happens, EPClosed event
+            // should be ignored.
+            if( aData == EPbCmdStop )
+                {
+                break;
+                }
+
+            Cleanup();
+
+            // If iProxyState is EStateClosing, initialise of 
+            // localplaybackplugin is failed -> send initialised event with
+            // an error code to the user.
+            // Otherwise forward event to the user normally.
+            if( iProxyState == EStateClosing )
+                {
+                iObs->HandlePluginEvent( 
+                    MMPXPlaybackPluginObserver::EPInitialised,
+                    0, KErrNotSupported );
+                }
+            else
+                {
+                aError = TUpnpPluginsErrorTranslation::ErrorTranslate( 
+                        aError );
+                iObs->HandlePluginEvent( aEvent, aData, aError );
+                }
+            iProxyState = EStateUninitialised;
+            break;
+            }
+        default:
+            {
+            __LOG( "DownloadProxy: Default event?" );
+            break;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::HandleProperty
+// --------------------------------------------------------------------------
+// 
+void CUPnPMusicDownloadProxy::HandleProperty( TMPXPlaybackProperty aProperty,
+    TInt aValue, TInt aError )
+    {
+    __LOG1( "DownloadProxy::HandleProperty [%d]", this );
+        
+    iObs->HandleProperty( aProperty, aValue, aError );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::HandleSubPlayerNames
+// --------------------------------------------------------------------------
+// 
+void CUPnPMusicDownloadProxy::HandleSubPlayerNames( TUid aPlayer, 
+    const MDesCArray* aSubPlayers, TBool aComplete, TInt aError )
+    {
+    iObs->HandleSubPlayerNames( aPlayer, aSubPlayers, aComplete, aError );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::HandleMedia
+// --------------------------------------------------------------------------
+// 
+void CUPnPMusicDownloadProxy::HandleMedia( const CMPXMedia& aProperties,
+    TInt aError )
+    {
+    __LOG1( "DownloadProxy::HandleMedia [%d]", this );
+        
+    iObs->HandleMedia( aProperties, aError );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPMusicDownloadProxy::CleanUpSession
+// --------------------------------------------------------------------------
+// 
+void CUPnPMusicDownloadProxy::Cleanup()
+    {
+    __LOG1( "DownloadProxy::Cleanup [%d]", this );
+    if( iTrack )
+        {
+        delete iTrack;
+        iTrack = 0;
+        }
+    __LOG( "DownloadProxy::Cleanup - End");
+    }
+