upnpframework/upnpaiwengine/src/upnpaiwengine.cpp
changeset 0 7f85d04be362
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpframework/upnpaiwengine/src/upnpaiwengine.cpp	Thu Dec 17 08:52:00 2009 +0200
@@ -0,0 +1,1709 @@
+/*
+* Copyright (c) 2005-2007 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:  Implementation of the class CUPnPAiwEngine.
+ *
+*/
+
+
+// INCLUDE FILES
+// System
+#include <bautils.h>
+#include <AknWaitDialog.h>
+#include <aknnotewrappers.h>
+#include <StringLoader.h>
+#include <utf.h>
+
+// Upnp stack
+#include <upnpitem.h>
+
+// avcontroller api
+#include "upnpavcontroller.h"
+#include "upnpavcontrollerfactory.h"
+#include "upnpavrenderingsession.h"
+#include "upnpavsessionbase.h"
+#include "upnpavdevice.h"
+
+// avcontroller / avcontroller helper api
+#include "upnpitemresolver.h"
+#include "upnpitemresolverfactory.h"
+#include "upnpitemutility.h"
+#include "upnpresourceselector.h"
+
+// upnpframework internal api's
+#include "upnpfiletransferengine.h"     // Upnp Fw / UpnpFileTransferEngine
+#include "upnpcommonutils.h"            // Upnp Fw / UpnpUtilities
+
+// aiw engine internal
+#include <upnpaiwengineresources.rsg>   // Upnp Fw / UpnpAiwEngine
+#include "upnpaiwengine.h"                // Upnp Fw / UpnpAiwEngine
+#include "upnpaiwtimer.h"               // Upnp Fw / UpnpAiwEngine
+
+// logging
+_LIT( KComponentLogfile, "upnpaiwengine.log" );
+#include "upnplog.h"
+
+const TInt KSlash = 92;
+const TInt KDot = 46;
+
+// CONSTANTS
+_LIT( KResFileName, "\\resource\\upnpaiwengineresources.rsc" );
+const TInt KAiwTimerIntervalInSeconds = 1;
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::NewL
+// NewL.
+// --------------------------------------------------------------------------
+//
+EXPORT_C CUPnPAiwEngine* CUPnPAiwEngine::NewL()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::NewL" );
+
+    CUPnPAiwEngine* self = NULL;
+
+    // If this is the first time we are getting the instance of this
+    // singleton class, create the instance and store it into the
+    // Thread Local Storage
+    if( !Dll::Tls() )
+        {
+        self = new (ELeave) CUPnPAiwEngine;
+
+        CleanupStack::PushL( self );
+        self->ConstructL();
+        CleanupStack::Pop( self );
+
+        TInt err = Dll::SetTls( static_cast<TAny*>( self ) );
+        if( err != KErrNone )
+            {
+            delete self;
+            self = NULL;
+            }
+        else
+            {
+            // Initialise the user counter to zero
+            self->InitialiseUserCounter();
+            }
+        }
+    else
+        {
+        self = static_cast<CUPnPAiwEngine*>( Dll::Tls() );
+        }
+
+    // Increase number of users by one
+    self->IncreaseUserCounter();
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::ReleaseInstance
+// Releases the instance.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::ReleaseInstance()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::ReleaseInstance" );
+
+    CUPnPAiwEngine* instance = NULL;
+
+    // Get the instance from the TLS if there is an instance
+    if( Dll::Tls() )
+        {
+        instance = static_cast<CUPnPAiwEngine*>( Dll::Tls() );
+        }
+
+    // If there still were an instance in the TLS
+    if( instance )
+        {
+
+        // Decrease the number of instance
+        instance->DecreaseUserCounter();
+
+        // If the instance count is now 0, empty the TLS
+        if( instance->UserCounter() <= 0 )
+            {
+            // Empty the TLS
+            TInt err = Dll::SetTls( NULL );
+            if( err )
+                {
+                // ignore
+                }
+
+            // Delete the instance
+            delete instance;
+            instance = NULL;
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// Constructor
+// --------------------------------------------------------------------------
+//
+CUPnPAiwEngine::CUPnPAiwEngine()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CUPnPAiwEngine" );
+
+    iRenderingSessionInUse = EFalse;
+    iVideoPlay = EFalse;
+    iFileName = NULL;
+    iVideoPlayCancel = EFalse;
+    iVideoPlayWait = EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// Destructor
+// --------------------------------------------------------------------------
+//
+CUPnPAiwEngine::~CUPnPAiwEngine()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::~CUPnPAiwEngine" );
+    // Delete resolvers
+    // Delete for resolvers is done using temporary variables so that we can
+    // first nullify the members and then delete the actual objects.
+    // This is because local resolver deletion uses active scheduler loops
+    // and therefore other asynchronous events may orrur. So we may end
+    // up here in Cleanup again, during the resolver is being deleted.
+    // if deletion is done the conventional way, the objects get deleted
+    // twice, which is not what we want. :-)
+    MUPnPItemResolver* tempResolver = iResolver;
+    iResolver = NULL;
+    delete tempResolver;
+    StopTimer();
+
+    // If wait note is shown, finish it
+    if (iWaitNoteDialog)
+        {
+        TRAP_IGNORE( iWaitNoteDialog->ProcessFinishedL() );
+        }
+
+    if (iRenderingSession && iAVController)
+        {
+        TRAP_IGNORE( iAVController->StopRenderingSession(
+                        *iRenderingSession ) );
+        iRenderingSession = NULL;
+        }
+
+    delete iCommonUI;
+
+    // Delete the UPnP AV Controller
+    delete iAVController;
+    delete iFileName;
+
+    // Un-load resource file
+    if (iResFileOffset)
+        {
+        CEikonEnv::Static()->DeleteResourceFile(iResFileOffset);
+        iResFileOffset = 0;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::ConstructL
+// Second phase constructor
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::ConstructL()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::ConstructL" );
+
+    iCoeEnv = CEikonEnv::Static();
+    RFs& fileSession = iCoeEnv->FsSession();
+
+    // Load resource file
+    TFileName rscFileName(KResFileName);
+    TFileName dllName;
+    Dll::FileName(dllName);
+    TBuf<2> drive = dllName.Left(2); // Drive letter followed by ':' 
+    rscFileName.Insert( 0, drive);
+
+    // Get the exact filename of the resource file
+    BaflUtils::NearestLanguageFile(fileSession, rscFileName);
+
+    // Check if the resource file exists or not
+    if ( !BaflUtils::FileExists(fileSession, rscFileName) )
+        {
+        __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, resource file does not \
+exist!" );
+        User::Leave(KErrNotFound);
+        }
+
+    if (iCoeEnv)
+        {
+        // Read the resource file offset
+        iResFileOffset = iCoeEnv->AddResourceFileL(rscFileName);
+        }
+
+    // Set initial state of the connection to the UPnPAVController
+    iCommonUI = CUPnPCommonUI::NewL();
+    iAVController = NULL;
+    iRenderingSession = NULL;
+    iEngineState = EUPnPEngineNotConnected;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::SetEngineObserver
+// Sets the observer instance.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::SetEngineObserver(
+        MUPnPAiwEngineObserver* aObserver )
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::SetEngineObserver" );
+
+    if( aObserver )
+        {
+        iObserver = aObserver;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::RemoveEngineObserver
+// Sets the observer instance.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::RemoveEngineObserver()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::RemoveEngineObserver" );
+
+    iObserver = NULL;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::EngineState
+// Gets the state of the UPnP AIW Engine.
+// --------------------------------------------------------------------------
+//
+EXPORT_C TUPnPEngineState CUPnPAiwEngine::EngineState()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::EngineState" );
+
+    return iEngineState;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::OpenExternalMediaL
+// Opens the External media UI.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::OpenExternalMediaL()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::OpenExternalMediaL" );
+
+    TInt status = KErrNone;
+
+    if( !iAVController &&
+            iEngineState == EUPnPEngineNotConnected )
+        {
+        TRAP( status,
+                iAVController =
+                UPnPAVControllerFactory::NewUPnPAVControllerL() );
+
+        if( status == KErrNone &&
+                iAVController )
+            {
+            // Update engine state
+            iEngineState = EUPnPEngineBrowsingHomeNetwork;
+            TInt leaveCode = KErrNone;
+
+            TRAP( leaveCode,
+                    status = iCommonUI->ExecuteDeviceDialogL( *iAVController ) );
+
+            // Handle status and leave codes
+            if( leaveCode != KErrNone &&
+                    status == KErrNone )
+                {
+                status = leaveCode;
+                }
+
+            // Clean up and return the engine state
+            delete iAVController;
+            iAVController = NULL;
+            iEngineState = EUPnPEngineNotConnected;
+            }
+        else // If the instantiation of UpnpAvController fails
+
+            {
+            TRAP_IGNORE( ShowConnectionErrorL() );
+            status = KErrCouldNotConnect;
+            }
+        }
+    else // If the UpnpAvController is already instantiated
+
+        {
+        status = KErrInUse;
+        }
+
+    if( status != KErrNone )
+        {
+        User::Leave( status );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::EnableExternalL
+// Enables the showing of local media files on a remote renderer device.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::EnableExternalL()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::EnableExternalL" );
+
+    TInt status = KErrNone;
+
+    if( !iAVController &&
+            iEngineState == EUPnPEngineNotConnected )
+        {
+        TRAP( status,
+                iAVController =
+                UPnPAVControllerFactory::NewUPnPAVControllerL() );
+
+        if( status == KErrNone &&
+                iAVController )
+            {
+            iAVController->SetDeviceObserver( *this );
+            TRAP( status, StartRenderingSessionL(
+                            EUPnPAiwEngineTargetDeviceWithImageSupport ) );
+
+            // If the rendering session was created successfully
+            if( status == KErrNone &&
+                    iRenderingSession )
+                {
+                // Start local file sharing
+                TRAP( status,
+                        StartLocalFileSharingL( iRenderingSession ) );
+                    {
+                    // If the file sharing failed to start, undo the enable
+                    // external by calling disable external.
+                    if( status != KErrNone )
+                        {
+                        DisableExternal();
+                        }
+                    }
+                }
+            else
+                {
+                delete iAVController;
+                iAVController = NULL;
+                iEngineState = EUPnPEngineNotConnected;
+                }
+            }
+        else // If the instantiation of UpnpAvController fails
+
+            {
+            TRAP_IGNORE( ShowConnectionErrorL() );
+            status = KErrCouldNotConnect;
+            }
+        }
+    else
+        {
+        status = KErrInUse;
+        }
+
+    if( status != KErrNone )
+        {
+        User::Leave( status );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::DisableExternal
+// Disables the showing of local media files on a remote renderer device.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::DisableExternal()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::DisableExternal" );
+
+    if( iAVController )
+        {
+        if( iRenderingSession )
+            {
+            // If STOP action is required, use the timer to delay the
+            // destruction (give some time for AvController to send the STOP
+            // action message)
+            if( iEngineState == EUPnPEngineActive )
+                {
+                TRAP_IGNORE( iRenderingSession->StopL() );
+                StartTimer();
+                }
+            else
+                {
+                // Stop local file sharing
+                TRAP_IGNORE( iRenderingSession->ReleaseLocalMSServicesL() );
+
+                // Stop the rendering session
+                TRAP_IGNORE( iAVController->StopRenderingSession(
+                                *iRenderingSession ) );
+                iRenderingSession = NULL;
+                }
+            }
+
+        // Delete the UPnP AV Controller
+        delete iAVController;
+        iAVController = NULL;
+        }
+
+    // Update engine state
+    iRenderingSessionInUse = EFalse;
+    iEngineState = EUPnPEngineNotConnected;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::PlayL
+// Plays (sends for rendering) local media file using the selected
+// UPnP Media renderer.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::PlayL( const TDesC& aFileName )
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::PlayL" );
+
+    TInt status = KErrNone;
+
+    if( aFileName != KNullDesC )
+        {
+
+        if( iAVController &&
+                iRenderingSession &&
+                ( iEngineState == EUPnPEngineConnected ||
+                        iEngineState == EUPnPEngineActive ) )
+            {
+
+            // Check the file type
+            TUPnPItemType fileType = ETypeOther;
+            TRAPD( mimeError,
+                    fileType = UPnPCommonUtils::ResolveFileTypeL(
+                            aFileName ) );
+            if( mimeError == KErrNone )
+                {
+                if( fileType == ETypeAudio )
+                    {
+                    status = KErrNotSupported;
+                    if( iObserver )
+                        {
+                        iObserver->PlayCompleteL( status );
+                        }
+                    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, \
+audio files not supported!" );
+                    }
+                else if ( fileType == ETypeVideo )
+                    {
+                    if( iRenderingSessionInUse )
+                        {
+                        //if the previous operation not finished
+                        delete iFileName; iFileName = NULL;
+                        iFileName = aFileName.AllocL();
+                        iVideoPlayWait = ETrue;
+                        }
+                    else
+                        {
+                        TRAP( status, StartVideoPlayL( aFileName ) );
+                        }
+                    }
+                else if ( fileType == ETypeImage )
+                    {
+                    if( !iVideoPlay ) //if no video is being played
+
+                        {
+                        if( iRenderingSessionInUse )
+                            {
+                            //if the previous operation not finished
+                            iVideoPlayWait = EFalse;
+                            __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, \
+iRenderingSessionInUse: ETrue" );
+                            delete iFileName;
+                            iFileName = NULL;
+                            iFileName = aFileName.AllocL();
+                            }
+                        else
+                            {
+                            __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, \
+iRenderingSessionInUse: EFalse" );
+                            TRAP( status , CreateUpnpItemAndSetUriL( aFileName ) );
+                            if( KErrNone == status )
+                                {
+                                iRenderingSessionInUse = ETrue;
+                                }
+                            else
+                                {
+                                // Failed, notify MG, the image playing is
+                                // complete
+                                if( iObserver )
+                                    {
+                                    iObserver->PlayCompleteL( status );
+                                    }
+                                }
+                            }
+                        }
+                    else
+                        {
+                        //notify MG, the music playing is complete
+                        if( iObserver )
+                            {
+                            iObserver->PlayCompleteL( status );
+                            }
+                        }
+
+                    }
+                else // Unsupported file
+
+                    {
+                    status = KErrNotSupported;
+                    }
+                }
+            else // Failed to resolve MIME type
+
+                {
+                status = KErrArgument;
+                }
+            }
+        else // Rendering session not available (Enable External not done)
+
+            {
+            status = KErrNotReady;
+            }
+        }
+    else
+        {
+        status = KErrArgument;
+        }
+
+    if( status != KErrNone )
+        {
+        User::Leave( status );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::CopyToExternalL
+// Copies local files to a remote media server.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::CopyToExternalL(
+        RPointerArray<TDesC>& aFileNames )
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CopyToExternalL" );
+
+    // Check parameters
+    if( aFileNames.Count() <= 0 )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    // Check engine state
+    if( iAVController )
+        {
+        User::Leave( KErrInUse );
+        }
+
+    // Create UPnPAVController
+    TRAPD( avControllerError,
+            iAVController = UPnPAVControllerFactory::NewUPnPAVControllerL() );
+    if( avControllerError != KErrNone )
+        {
+        TRAP_IGNORE( ShowConnectionErrorL() );
+        User::Leave( KErrCouldNotConnect );
+        }
+
+    // Update engine state
+    iEngineState = EUPnPEngineConnected;
+
+    // Do the transfer
+    TRAPD( transferError,
+            TransferToExternalL( EAiwEngineCopy, aFileNames, KNullDesC ) );
+
+    // Clean up
+    delete iAVController;
+    iAVController = NULL;
+
+    // Update engine state
+    iEngineState = EUPnPEngineNotConnected;
+
+    if( transferError != KErrNone )
+        {
+        User::Leave( transferError );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::CopyToExternalL
+// Copies local files to a remote media server.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::CopyPlaylistToExternalL(
+        const TDesC& aPlaylistName,
+        RPointerArray<TDesC>& aFileNames )
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CopyPlaylistToExternalL" );
+
+    // Check parameters
+    if( aFileNames.Count() <= 0 ||
+            aPlaylistName == KNullDesC )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    // Check engine state
+    if( iAVController )
+        {
+        User::Leave( KErrInUse );
+        }
+
+    // Create UPnPAVController
+    TRAPD( avControllerError,
+            iAVController = UPnPAVControllerFactory::NewUPnPAVControllerL() );
+    if( avControllerError != KErrNone )
+        {
+        TRAP_IGNORE( ShowConnectionErrorL() );
+        User::Leave( KErrCouldNotConnect );
+        }
+
+    // Update engine state
+    iEngineState = EUPnPEngineConnected;
+
+    // Do the transfer
+    TRAPD( transferError,
+            TransferToExternalL( EAiwEngineCopyPlaylist,
+                    aFileNames,
+                    aPlaylistName ) );
+
+    // Clean up
+    delete iAVController;
+    iAVController = NULL;
+
+    // Update engine state
+    iEngineState = EUPnPEngineNotConnected;
+
+    if( transferError != KErrNone )
+        {
+        User::Leave( transferError );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::MoveToExternalL
+// Moves local files to a remote media server.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::MoveToExternalL(
+        RPointerArray<TDesC>& aFileNames )
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::MoveToExternalL" );
+
+    // Check parameters
+    if( aFileNames.Count() <= 0 )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    // Check engine state
+    if( iAVController )
+        {
+        User::Leave( KErrInUse );
+        }
+
+    // Create UPnPAVController
+    TRAPD( avControllerError,
+            iAVController = UPnPAVControllerFactory::NewUPnPAVControllerL() );
+    if( avControllerError != KErrNone )
+        {
+        TRAP_IGNORE( ShowConnectionErrorL() );
+        User::Leave( KErrCouldNotConnect );
+        }
+
+    // Update engine state
+    iEngineState = EUPnPEngineConnected;
+
+    // Do the transfer
+    TRAPD( transferError,
+            TransferToExternalL( EAiwEngineMove, aFileNames, KNullDesC ) );
+
+    // Clean up
+    delete iAVController;
+    iAVController = NULL;
+
+    // Update engine state
+    iEngineState = EUPnPEngineNotConnected;
+
+    if( transferError != KErrNone )
+        {
+        User::Leave( transferError );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::TransferToExternalL
+// Transfers (copies/moves) local files/playlists to a remote media server.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::TransferToExternalL(TUPnPAiwEngineTransferMode aMode,
+        RPointerArray<TDesC>& aFilePaths, const TDesC& aPlaylistName)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::TransferToExternalL" );
+
+    // Parameters were already checked
+
+    // Select the target server device
+    // Title should be according to ui spec.
+    TUPnPDialogTitle title = EUPnPCopyToTitle;
+    if (aMode == EAiwEngineMove)
+        {
+        title = EUPnPMoveToTitle;
+        }
+    CUpnpAVDevice* targetDevice = SelectDeviceL(
+            EUPnPSearchServerDevicesWithCopyCapability, title);
+
+    CleanupStack::PushL(targetDevice);
+
+    // Create a browsing session
+    TInt status = KErrNone;
+    MUPnPAVBrowsingSession* browsingSession= NULL;
+    TRAP( status, browsingSession =
+            &iAVController->StartBrowsingSessionL( *targetDevice ) );
+
+    if (status == KErrNone && browsingSession)
+        {
+        // Create a file transfer engine instance
+        CUpnpFileTransferEngine* ftEngine= NULL;
+        TRAP( status, 
+                ftEngine = CUpnpFileTransferEngine::NewL( browsingSession ) );
+        if ( status == KErrNone && ftEngine )
+            {
+            CleanupStack::PushL( ftEngine );
+
+            // Update engine state
+            iEngineState = EUPnPEngineActive;
+            
+            // Number of files in the array.
+            TInt count = aFilePaths.Count();
+
+            // Do the copy/move
+            if ( aMode == EAiwEngineMove )
+                {
+                TRAP( status, ftEngine->MoveLocalFilesToRemoteServerL(
+                                &aFilePaths ) );
+                }
+            else if ( aMode == EAiwEngineCopyPlaylist)
+                {
+                TRAP( status, ftEngine->CopyLocalPlaylistToRemoteServerL(
+                                aPlaylistName,
+                                &aFilePaths ) );
+                }
+            else
+                {
+                TRAP( status, ftEngine->CopyLocalFilesToRemoteServerL(
+                                &aFilePaths ) );
+                }
+        
+            // Clean up
+            // aFilePaths is not updates until ftEngine is deleted!
+            CleanupStack::PopAndDestroy( ftEngine );
+            ftEngine = NULL;
+            
+            // Update engine state
+            if ( status == KErrNone )
+                {
+                iEngineState = EUPnPEngineConnected;
+
+                // Shows proper info note.
+                //
+                // Calculate number of transferred files based on original 
+                // file count and items remaining in aFilePaths 
+                // (those were NOT transferred)
+                ShowTransferInfoNoteL( 
+                        aMode, 
+                        count - aFilePaths.Count(), 
+                        *targetDevice );
+                }
+            else if (KErrSessionClosed == status || KErrCouldNotConnect == status 
+			           || KErrDisconnected == status )
+                {
+                iEngineState = EUPnPEngineConnectionLost;
+                if ( aMode != EAiwEngineMove )
+                    {
+                    ShowConnectionLostCopyErrorL();
+                    }
+                else
+                    {
+                    ShowConnectionErrorL();
+                    }
+                }
+            else if ( KErrNotFound == status )
+                {
+                 ShowTransferInfoNoteL (
+                                       aMode,
+                                       0,
+                                       *targetDevice );
+                }
+            else
+                {
+                iEngineState = EUPnPEngineConnected;
+                }
+            }
+
+        // Stop browsing session
+        iAVController->StopBrowsingSession( *browsingSession );
+        }
+
+    // Clean up
+    CleanupStack::PopAndDestroy( targetDevice );
+    targetDevice = NULL;
+
+    // Get the titles (of the files that failed to be transfered) from
+    // the item array and store them in the file name array. 
+    TChar slash( KSlash );
+    TChar dot( KDot );
+    TInt fileCount = aFilePaths.Count();
+    RPointerArray<TDesC16> fileTitles;
+    for ( TInt index = 0; index < fileCount; index++ )
+        {
+        TInt offset1 = aFilePaths[index]->LocateReverse( slash );
+        TInt offset2 = aFilePaths[index]->LocateReverse( dot );
+
+        HBufC16* fileTitle= NULL;
+
+        if ( KErrNotFound != offset1 && KErrNotFound != offset2 && 
+             offset2 > ( offset1 + 1 ) )
+            {
+
+            fileTitle = aFilePaths[index]->
+            Mid( ( offset1 + 1 ), ( offset2 - offset1 - 1 ) ).Alloc();
+
+            }
+        if (fileTitle)
+            {
+            fileTitles.Append(fileTitle);
+            }
+        }
+    aFilePaths.ResetAndDestroy();
+    for (TInt index = 0; index < fileTitles.Count(); index++)
+        {
+        aFilePaths.Append(fileTitles[index]);
+        }
+
+    fileTitles.Reset();
+    fileTitles.Close();
+
+    if (status != KErrNone)
+        {
+        User::Leave(status);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::StartRenderingSessionL
+// Starts a rendering session with UpnpAvController. Queries the target
+// rendering device.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::StartRenderingSessionL(TUPnPAiwEngineDeviceType aType)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::StartRenderingSessionL" );
+
+    TInt status = KErrNone;
+
+    if (iAVController)
+        {
+        if ( !iRenderingSession)
+            {
+            CUpnpAVDevice* tempDevice = CUpnpAVDevice::NewL();
+            CleanupStack::PushL(tempDevice);
+
+            // Launch the device selection dialog
+
+            if (aType == EUPnPAiwEngineTargetDeviceWithAudioSupport)
+                {
+                status = iCommonUI->SelectDeviceL( *iAVController,
+                        *tempDevice,
+                        EUPnPSearchRenderingDevicesWithAudioCapability,
+                        EUPnPSelectDeviceTitle);
+                }
+            else
+                if (aType
+                        == EUPnPAiwEngineTargetDeviceWithImageAndVideoSupport)
+                    {
+                    status = iCommonUI->SelectDeviceL( *iAVController,
+                            *tempDevice,
+                            EUPnPSearchRenderingDevicesWithVideoCapability,
+                            EUPnPSelectDeviceTitle);
+                    }
+                else
+                    if (aType == EUPnPAiwEngineTargetDeviceWithImageSupport)
+                        {
+                        status
+                                = iCommonUI->SelectDeviceL(
+                                        *iAVController,
+                                        *tempDevice,
+                                        EUPnPSearchRenderingDevicesWithImageCapability,
+                                        EUPnPSelectDeviceTitle);
+                        }
+                    else
+                        {
+                        status = KErrNotSupported;
+                        }
+
+            if (status == KErrNone)
+                {
+                // Create a rendering session and register to observe the
+                // callbacks
+                __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, \
+creating rendering session." );
+                iRenderingSession
+                        = &(iAVController->StartRenderingSessionL( *tempDevice) );
+                iRenderingSession->SetObserver( *this);
+                __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, \
+rendering session created." );
+
+                // Update the engine state
+                iEngineState = EUPnPEngineConnected;
+                }
+
+            // Clean up
+            CleanupStack::PopAndDestroy(tempDevice);
+            tempDevice = NULL;
+            }
+        else
+            {
+            status = KErrInUse;
+            }
+        }
+    else
+        {
+        status = KErrNotReady;
+        }
+
+    if (status != KErrNone)
+        {
+        User::Leave(status);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::InteractOperationComplete
+// UPnP AV Controller calls this method to indicate that the requested
+// interaction operation (play, stop, etc.) is complete.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::InteractOperationComplete(TInt aError,
+        TUPnPAVInteractOperation aOperation)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::InteractOperationComplete" );
+
+    if (iObserver && !iVideoPlayCancel)
+        {
+        // If the play operation is complete (stop) or the play fails, do
+        // the call back
+        if (aOperation == EUPnPAVPlay || aOperation == EUPnPAVPlayUser
+                || aOperation == EUPnPAVStop || aOperation == EUPnPAVStopUser)
+            {
+            iEngineState = EUPnPEngineConnected;
+            TRAP_IGNORE( iObserver->PlayCompleteL( aError ) );
+            }
+        }
+    if (aOperation == EUPnPAVPlay || aOperation == EUPnPAVStop)
+        {
+        iRenderingSessionInUse = EFalse;
+        if (iFileName) // If there is a pending item
+            {
+            __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, pending item" );
+            TRAP_IGNORE( InitPlayL() );
+            delete iFileName;
+            iFileName = NULL;
+            iVideoPlayCancel = EFalse; // No need to send StopL
+            }
+        else
+            {
+            __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, no pending item" );
+
+            if (iVideoPlayCancel)
+                {
+                __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, stop previous \
+video item," );
+                iRenderingSessionInUse = ETrue;
+                TRAP_IGNORE( iRenderingSession->StopL() );
+                iVideoPlayCancel = EFalse; //StopL sent
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::SetURIResult
+// UPnP AV Controller calls this method to indicate that ...
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::SetURIResult(TInt aError)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::SetURIResult" );
+
+    iRenderingSessionInUse = EFalse;
+    if (aError != KErrNone && iObserver && !iVideoPlayCancel)
+        {
+        TRAP_IGNORE( iObserver->PlayCompleteL( aError ) );
+        }
+    else
+        if ( !iRenderingSession)
+            {
+            if (iObserver)
+                {
+                TRAP_IGNORE( iObserver->PlayCompleteL( KErrNotReady ) );
+                }
+            }
+
+    if (iFileName) //if there is a pending item
+        {
+        __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, pending item" );
+        TRAP_IGNORE( InitPlayL() );
+        delete iFileName;
+        iFileName = NULL;
+        iVideoPlayCancel = EFalse; //no need to send StopL        
+        }
+    else
+        if ( !iVideoPlayCancel)
+            {
+            __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, no pending item" );
+            __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, no cancellation from \
+video play" );
+            TRAP( aError, iRenderingSession->PlayL() );
+            //if play failed, send the result right way
+            if (aError && iObserver)
+                {
+                TRAP_IGNORE( iObserver->PlayCompleteL( aError ) );
+                }
+            else
+                if (KErrNone == aError)
+                    {
+                    iRenderingSessionInUse = ETrue;
+                    }
+            }
+        else
+            if (iVideoPlayCancel)
+                {
+                __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, no pending item" );
+                __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, stop previous \
+video item" );
+                TRAP_IGNORE( iRenderingSession->StopL() );
+                iRenderingSessionInUse = ETrue;
+                iVideoPlayCancel = EFalse; //StopL sent
+                }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::ReleaseUpnpResourceL
+// Release Upnp resouces
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::ReleaseUpnpResourceL()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::ReleaseUpnpResourceL" );
+
+    // Inform the client about the connection lost
+    if (iObserver)
+        {
+        iObserver->ConnectionLostL();
+        }
+
+    // Stop the rendering session
+    if ( iRenderingSession && iAVController )
+        {
+        //iRenderingSession->ReleaseLocalMSServicesL();
+        iRenderingSession->RemoveObserver();
+        iAVController->StopRenderingSession( *iRenderingSession);
+        iRenderingSession = NULL;
+        }
+
+    // Disconnect UPnPAVController
+    delete iAVController;
+    iAVController = NULL;
+
+    iRenderingSessionInUse = EFalse;
+    // Update engine state
+    iEngineState = /*EUPnPEngineConnectionLost;*/EUPnPEngineNotConnected;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::WLANConnectionLost
+// UPnP AV Controller calls this method to indicate that ...
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::WLANConnectionLost()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::WLANConnectionLost" );
+
+    iFileSharingError = KErrDisconnected;
+    if ( iFileSharingActivationWaitNote )
+        {
+        TRAP_IGNORE( iFileSharingActivationWaitNote->ProcessFinishedL() );
+        }
+    TRAP_IGNORE( iCommonUI->DismissDialogL( KErrDisconnected ) );
+    TRAP_IGNORE( ReleaseUpnpResourceL() );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::MediaRendererDisappeared
+// Notifies that the Media Renderer we have a session with has disappeared. 
+// Session is now unusable and must be closed. 
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::MediaRendererDisappeared(
+        TUPnPDeviceDisconnectedReason aReason)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::MediaRendererDisappeared" );
+
+    if (EDisconnected == aReason)
+        {
+        TRAP_IGNORE( ShowConnectionErrorL() );
+        TRAP_IGNORE( ReleaseUpnpResourceL() );
+        }
+
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::InitialiseUserCounter
+// Sets the initial value of the user counter to zero.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::InitialiseUserCounter()
+    {
+    iNumberOfUsers = 0;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::IncreaseUserCounter
+// Increases the value of the user counter by one.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::IncreaseUserCounter()
+    {
+    iNumberOfUsers++;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::DecreaseUserCounter
+// Decreases the value of the user counter by one.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::DecreaseUserCounter()
+    {
+    iNumberOfUsers--;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::UserCounter
+// Gets the value of the user counter.
+// --------------------------------------------------------------------------
+//
+TInt CUPnPAiwEngine::UserCounter() const
+    {
+    return iNumberOfUsers;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::StartTimer()
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::StartTimer()
+    {
+    // Stop the timer 
+    StopTimer();
+
+    // Start the timer 
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, starting timer" );
+    TRAPD( err,
+            iUPnPAiwTimer = CUPnPAiwTimer::NewL( KAiwTimerIntervalInSeconds,
+                    this ) )
+    ;
+    if (err)
+        {
+        __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, timer start failed!" );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::StopTimer()
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::StopTimer()
+    {
+    // Stop the timer if it is running
+    if (iUPnPAiwTimer)
+        {
+        __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, stopping timer" );
+        delete iUPnPAiwTimer;
+        iUPnPAiwTimer = NULL;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::TimerCallback
+// Callback method for the UPnPAiWTimer.
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::TimerCallback()
+    {
+    StopTimer();
+    if( iAVController )
+        {
+        if( iRenderingSession )
+            {
+            // Stop local file sharing
+            TRAP_IGNORE( iRenderingSession->ReleaseLocalMSServicesL() );
+
+            // Stop the rendering session
+            TRAP_IGNORE( iAVController->StopRenderingSession(
+                            *iRenderingSession ) );
+            iRenderingSession = NULL;
+            }
+
+        // Disconnect UPnPAVController
+        delete iAVController;
+        iAVController = NULL;
+
+        // Update engine state
+        iEngineState = EUPnPEngineNotConnected;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::ShowConnectionErrorL()
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAiwEngine::ShowConnectionErrorL()
+    {
+    iCommonUI->DisplayConnectionErrorNoteL();
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::ShowConnectionLostCopyErrorL()
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::ShowConnectionLostCopyErrorL()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::ShowConnectionLostErrorL" );
+    iCommonUI->DisplayConnectionLostCopyErrorNoteL();
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::ShowTransferInfoNoteL
+// Show correct info note after file transfer is completed.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::ShowTransferInfoNoteL(
+        TUPnPAiwEngineTransferMode aMode,
+        TInt aCount, 
+        const CUpnpAVDevice& aServerName ) const
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::ShowTransferInfoNoteL" );
+
+    // Converts device name into unicode string.
+    HBufC* deviceString = CnvUtfConverter::ConvertToUnicodeFromUtf8L(
+            aServerName.FriendlyName() );
+    CleanupStack::PushL( deviceString );
+
+    HBufC* infoText= NULL;
+    if ( aCount == 1 )
+        {
+        if ( aMode == EAiwEngineMove )
+            {
+            // File moved.
+            infoText = StringLoader::LoadLC( 
+                    R_AIW_INFO_MOVE_EXT_ONE_TEXT, 
+                    *deviceString );
+            }
+        else
+            {
+            // File copied.
+            infoText = StringLoader::LoadLC( 
+                    R_AIW_INFO_COPY_EXT_ONE_TEXT,
+                    *deviceString );
+            }
+        }
+    else
+        {
+        if ( aMode == EAiwEngineMove )
+            {
+            // Files moved.
+            infoText = StringLoader::LoadLC(
+                    R_AIW_INFO_MOVE_EXT_MANY_TEXT,
+                    *deviceString,
+                    aCount);
+            }
+        else
+            {
+            // Files copied.
+            infoText = StringLoader::LoadLC( 
+                    R_AIW_INFO_COPY_EXT_MANY_TEXT,
+                    *deviceString,
+                    aCount );
+            }
+        }
+
+    // Shows the dialog.
+    CAknInformationNote* infoNote = 
+        new ( ELeave ) CAknInformationNote( ETrue );
+    infoNote->ExecuteLD( *infoText );
+    
+    CleanupStack::PopAndDestroy( infoText );
+    CleanupStack::PopAndDestroy( deviceString );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::ReserveLocalMSServicesCompleted
+// Notifies that the Media Server startup has completed.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::ReserveLocalMSServicesCompleted(TInt aError)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::\
+ReserveLocalMSServicesCompleted" );
+
+    iFileSharingError = aError;
+    if (aError == KErrNone)
+        {
+        iLocalFileSharingActivated = ETrue;
+        }
+    if (iFileSharingActivationWaitNote)
+        {
+        TRAP_IGNORE( iFileSharingActivationWaitNote->ProcessFinishedL() );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::StartLocalFileSharingL
+// Waits for local media server file sharing activation (or user cancel).
+// --------------------------------------------------------------------------
+void CUPnPAiwEngine::StartLocalFileSharingL(MUPnPAVSessionBase *aSession)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::StartLocalFileSharingL" );
+
+    // Leave if the parameter is not valid
+    if ( !aSession)
+        {
+        User::Leave(KErrArgument);
+        }
+
+    // Initialize the sharing error variable
+    iFileSharingError = KErrNone;
+    iLocalFileSharingActivated = EFalse;
+
+    // Start the local media server
+    aSession->ReserveLocalMSServicesL();
+
+    // Instantiate and launch the wait note until the sharing is
+    // enabled of user cancels the operation
+    if ( !iLocalFileSharingActivated && iFileSharingError == KErrNone)
+        {
+        // Instantiate and launch the wait note until the sharing is
+        // enabled of user cancels the operation
+        iFileSharingActivationWaitNote = new(ELeave)CAknWaitDialog(
+                ( REINTERPRET_CAST( CEikDialog**,
+                                &iFileSharingActivationWaitNote ) ), ETrue );
+        iFileSharingActivationWaitNote->SetCallback( this);
+        TRAPD( fileSharingActivationError,
+                iFileSharingActivationWaitNote->ExecuteLD(
+                        R_AIW_ENABLE_SHARING_WAIT_NOTE ) )
+        ;
+
+        // Cancel sharing activation is user pressed cancel
+        if (iFileSharingError == KErrCancel)
+            {
+            TRAP_IGNORE( aSession->CancelReserveLocalMSServicesL() );
+            }
+
+        // If sharing failed, and the user did not cancel the operations,
+        // forward the leave code.
+        if (fileSharingActivationError != KErrNone && iFileSharingError
+                != KErrCancel)
+            {
+            iFileSharingError = fileSharingActivationError;
+            }
+        }
+
+    if (iFileSharingError != KErrNone)
+        {
+        User::Leave(iFileSharingError);
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::DialogDismissedL
+// ProgressDialog call back method. Get's called when a dialog is
+// dismissed.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::DialogDismissedL(TInt aButtonId)
+    {
+    if (aButtonId == EAknSoftkeyCancel)
+        {
+        __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, user cancelled the file \
+sharing activation" );
+        iFileSharingError = KErrCancel;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::DialogDismissedL
+// Method for selecting a device.
+// --------------------------------------------------------------------------
+//
+CUpnpAVDevice* CUPnPAiwEngine::SelectDeviceL(
+        TUPnPDeviceTypesToSearch aDeviceType, TUPnPDialogTitle aDlgTitle)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::SelectDeviceL" );
+
+    CUpnpAVDevice* device= NULL;
+
+    // Leave if the engine is not in right state
+    if ( !iAVController)
+        {
+        User::Leave(KErrNotReady);
+        }
+    else
+        {
+        // Create new UpnpAvDevice instance
+        device = CUpnpAVDevice::NewL();
+        CleanupStack::PushL(device);
+
+        // Do the device selection
+        TInt ret = iCommonUI->SelectDeviceL( *iAVController, *device,
+                aDeviceType, aDlgTitle);
+
+        if (ret != KErrNone)
+            {
+            CleanupStack::PopAndDestroy(device);
+            device = NULL;
+            User::Leave(ret);
+            }
+        CleanupStack::Pop(device); // Will be returned from the method
+        }
+
+    return device;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::StarVideoPlayL
+// Method for Playing a local video
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::StartVideoPlayL(const TDesC& aFileName)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::StartVideoPlayL" );
+
+    //check if selected renderer supports playing video
+    TInt status = KErrNone;
+    if (iRenderingSession->Device().VideoCapability() )
+        {
+        // Launch the video player dialog to render the
+        // item on the selected rendering device.
+        MUPnPItemResolver* resolver = CreateResolverLC( aFileName );
+        
+        // Update engine state
+        iEngineState = EUPnPEngineActive;
+        iRenderingSessionInUse = ETrue;
+        iVideoPlay = ETrue;
+
+        status = iCommonUI->ExecuteVideoPlayerL( *iRenderingSession,
+                resolver->Item() );
+        iVideoPlay = EFalse;
+        iRenderingSessionInUse = EFalse;
+        
+        if (KErrSessionClosed == status || KErrDisconnected == status)
+            {
+            if (KErrSessionClosed == status)
+                {
+                ReleaseUpnpResourceL();
+                }
+            }
+        else
+            {
+            // Re-register to observe the rendering
+            // session and update engine state
+            iRenderingSession->RemoveObserver();
+            iRenderingSession->SetObserver( *this);
+            iEngineState = EUPnPEngineConnected;
+            }
+
+        //notify MG, the video playing is complete
+        if (iObserver)
+            {
+            iObserver->PlayCompleteL(status);
+            }
+
+        if (KErrCancel == status)
+            {
+            TRAP_IGNORE( iRenderingSession->StopL() );
+            iRenderingSessionInUse = ETrue;
+            iVideoPlayCancel = ETrue;
+            }
+        
+        CleanupStack::PopAndDestroy(); // resolver
+        }
+    else //if not
+        {
+        status = KErrNotSupported;
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::InitPlayL
+// Method for Playing a local file
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::InitPlayL()
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::InitPlayL" );
+
+    //if pending an item
+    TInt error = KErrNone;
+
+    if (iVideoPlay || iVideoPlayWait)
+        {
+        __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, start video play" );
+        TRAP_IGNORE( StartVideoPlayL( *iFileName ) );
+        iVideoPlayWait = EFalse;
+        }
+    else
+        {
+        __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine, start image play" );
+        TRAP( error , CreateUpnpItemAndSetUriL( *iFileName ) );
+        if (KErrNone == error)
+            {
+            iRenderingSessionInUse = ETrue;
+            }
+        else
+            {
+            iObserver->PlayCompleteL(error);
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::Wait
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::Wait()
+    {
+    StopWait();
+    iWait.Start();
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::StopWait
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::StopWait()
+    {
+    if (iWait.IsStarted() )
+        {
+        if (iWait.CanStopNow() )
+            {
+            iWait.AsyncStop();
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::CreateUpnpItemAndSetUriL
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::CreateUpnpItemAndSetUriL(const TDesC& aFileName)
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CreateUpnpItemAndSetUriL" );
+    
+    // Creates resolver to iResolver member variable.
+    MUPnPItemResolver* resolver = CreateResolverLC( aFileName );
+    
+    // Sets uri.
+    const CUpnpElement& element = UPnPItemUtility::ResourceFromItemL( 
+            iResolver->Item() );
+    iRenderingSession->SetURIL( element.Value(), iResolver->Item() );
+    
+    // Cleanup
+    CleanupStack::PopAndDestroy(); // resolver
+    
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CreateUpnpItemAndSetUriL -END" );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::ResolveComplete
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::ResolveComplete(
+        const MUPnPItemResolver& /*aResolver*/, 
+        TInt aError )
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::ResolveComplete" );
+    
+    iResolveResult = aError;
+    StopWait();
+    
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::ResolveComplete -END" );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::CreateResolverLC
+// --------------------------------------------------------------------------
+//
+ MUPnPItemResolver* CUPnPAiwEngine::CreateResolverLC( const TDesC& aFilePath )
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CreateResolverLC" );
+    
+    // If member variable exists, resolving operation is ongoing.
+    if ( iResolver )
+        {
+        User::Leave( KErrInUse );
+        }
+    
+    // Creates resolver
+    TUPnPSelectDefaultResource selector;
+    iResolver = UPnPItemResolverFactory::NewLocalItemResolverL( 
+            aFilePath,
+            *iAVController, 
+            selector );
+    CleanupStack::PushL( TCleanupItem( CleanupResolver, this ) );
+    
+    // Starts async resolver.
+    iResolveResult = KErrNone;
+    iResolver->ResolveL( *this );
+    Wait();
+    
+    // If error occured, resolves it in here. It will cleanup resolver.
+    User::LeaveIfError( iResolveResult );
+    
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CreateResolverLC -END" );
+    
+    return iResolver;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAiwEngine::CleanupResolver
+// Static method to cleanup resolver object.
+// --------------------------------------------------------------------------
+//
+void CUPnPAiwEngine::CleanupResolver( TAny* aAiwEngine )
+    {
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CleanupResolver" );
+    
+    CUPnPAiwEngine* aiwEngine = reinterpret_cast<CUPnPAiwEngine*>( aAiwEngine );
+    if ( aiwEngine )
+        {
+        MUPnPItemResolver* tempResolver = aiwEngine->iResolver;
+        aiwEngine->iResolver = NULL;
+        delete tempResolver;
+        __LOG( "[UpnpAiwEngine]\t\t Resolver cleaned up." );
+        }
+    
+    __LOG( "[UpnpAiwEngine]\t CUPnPAiwEngine::CleanupResolver -END" );
+    }
+
+// End of file