--- /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