upnpmpxplugins/upnpplaybackplugins/src/upnpmusicdownloadproxy.cpp
author William Roberts <williamr@symbian.org>
Fri, 11 Jun 2010 16:24:51 +0100
branchGCC_SURGE
changeset 22 dfcf83b5d60e
parent 0 7f85d04be362
permissions -rw-r--r--
Branch for GCC_SURGE fixes

/*
* 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");
    }