diff -r dec420019252 -r 4f111d64a341 videoplayerapp/videoplayerengine/src/mpxvideoplayerappuiengine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoplayerapp/videoplayerengine/src/mpxvideoplayerappuiengine.cpp Thu Apr 01 22:38:49 2010 +0300 @@ -0,0 +1,1463 @@ +/* +* Copyright (c) 2009 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: CMpxVideoPlayerAppUiEngine + * +*/ + +// Version : %version: 3 % + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "mpxvideoplayerappuiengine.h" +#include "mpxvideoplayerconstants.h" +#include "mpxvideoembeddedpdlhandler.h" +#include "mpxvideoplaybackwrapper.h" +#include "mpxhbvideocommondefs.h" + +#include "mpxvideo_debug.h" + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::CMpxVideoPlayerAppUiEngine +// ------------------------------------------------------------------------------------------------- +// +CMpxVideoPlayerAppUiEngine::CMpxVideoPlayerAppUiEngine( QMpxVideoPlaybackWrapper* aWrapper ) + : iPlaybackUtility( NULL ), + iCollectionUtility( NULL ), + iExitAo( NULL ), + iRecognizer( NULL ), + iExtAccessPointId( KErrUnknown ), + iMultilinkPlaylist( EFalse ), + iSeekable( ETrue ), + iUpdateSeekInfo( EFalse ), + iPlaybackWrapper( aWrapper ) +{ +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::NewL +// ------------------------------------------------------------------------------------------------- +// +CMpxVideoPlayerAppUiEngine* CMpxVideoPlayerAppUiEngine::NewL( QMpxVideoPlaybackWrapper* aWrapper ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::NewL()")); + + CMpxVideoPlayerAppUiEngine* self = new( ELeave) CMpxVideoPlayerAppUiEngine( aWrapper ); + + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::ConstructL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::ConstructL() +{ + iRecognizer = CMediaRecognizer::NewL(); + + // + // Create the Collection Utility + // + + // + // Workaround. Embedded is not supported yet. + // + //if ( ! iAppUi->IsEmbedded() ) + if ( ETrue ) + { + TUid collectionMode( KUidMpxVideoPlayerApplication ); + + iCollectionUtility = MMPXCollectionUtility::NewL( this, collectionMode ); + } + + // + // Create Active Object for exiting the application + // + iExitAo = CIdle::NewL( CActive::EPriorityStandard ); +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::CreateCollectionUtilityMemberVariablesL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::CreateCollectionUtilityMemberVariablesL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::CreateCollectionUtilityMemberVariablesL()")); + + if ( ! iCollectionUtility ) + { + // PLAYLIST default mode + iCollectionUtility = MMPXCollectionUtility::NewL( this ); + } + + if ( ! iCollectionUiHelper ) + { + iCollectionUiHelper = CMPXCollectionHelperFactory::NewCollectionUiHelperL(); + } +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::CreatePlaybackUtilityMemberVariablesL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::CreatePlaybackUtilityMemberVariablesL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::CreatePlaybackUtilityMemberVariablesL()")); + + if ( ! iPlaybackUtility ) + { + // + // Create VideoHelix playback plugin + // + iPlaybackUtility = MMPXPlaybackUtility::UtilityL( EMPXCategoryVideo, KPbModeNewPlayer ); + MMPXPlayerManager& manager = iPlaybackUtility->PlayerManager(); + manager.SelectPlayerL( KVideoHelixPlaybackPluginUid ); + iPlaybackUtility->AddObserverL( *this ); + iPlaybackUtility->CommandL( EPbCmdSetAutoResume, EFalse ); + } +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::CreateEmbeddedPdlPlaybackUtilityMemberVariablesL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::CreateEmbeddedPdlPlaybackUtilityMemberVariablesL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::CreateEmbeddedPdlPlaybackUtilityMemberVariablesL()")); + + if ( ! iPlaybackUtility ) + { + iPlaybackUtility = MMPXPlaybackUtility::UtilityL( EMPXCategoryVideo, KPbModeNewPlayer ); + MMPXPlayerManager& manager = iPlaybackUtility->PlayerManager(); + manager.SelectPlayerL( KVideoHelixPlaybackPluginUid ); + iPlaybackUtility->AddObserverL( *this ); + iPlaybackUtility->CommandL( EPbCmdSetAutoResume, EFalse ); + } +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::~CMpxVideoPlayerAppUiEngine +// ------------------------------------------------------------------------------------------------- +// +CMpxVideoPlayerAppUiEngine::~CMpxVideoPlayerAppUiEngine() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::~CMpxVideoPlayerAppUiEngine()")); + + if ( iExitAo ) + { + delete iExitAo; + iExitAo = NULL; + } + + if ( iRecognizer ) + { + delete iRecognizer; + iRecognizer = NULL; + } + + if ( iPdlHandler ) + { + delete iPdlHandler; + iPdlHandler = NULL; + } + + if ( iCollectionUtility ) + { + iCollectionUtility->Close(); + } + + if ( iCollectionUiHelper ) + { + iCollectionUiHelper->Close(); + } + + if ( iPlaybackUtility ) + { + TRAP_IGNORE( iPlaybackUtility->CommandL( EPbCmdClose ) ); + TRAP_IGNORE( iPlaybackUtility->RemoveObserverL( *this ) ); + iPlaybackUtility->Close(); + } +} + +// --------------------------------------------------------------------------- +// From MMPXPlaybackObserver +// Handle playback message. +// --------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandlePlaybackMessage( CMPXMessage* aMessage, TInt aError ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandlePlaybackMessage()")); + + if ( aError == KErrNone && aMessage ) + { + TRAP_IGNORE( DoHandlePlaybackMessageL( *aMessage ) ); + } +} + +// --------------------------------------------------------------------------- +// From MMPXViewActivationObserver. +// Handle view activation. +// --------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleViewActivation( const TUid& /*aCurrentViewType*/, + const TUid& /*aPreviousViewType*/ ) +{ +} + +// --------------------------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::HandleAiwGenericParamListL() +// --------------------------------------------------------------------------------------------------------------------- +// +TInt CMpxVideoPlayerAppUiEngine::HandleAiwGenericParamListL( const CAiwGenericParamList* aParams ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleAiwGenericParamListL()")); + + TInt retVal = KErrNone; + + TInt index = 0; + + // + // Check if there is a terminate message. If it exists, exit the application. + // + TInt32 terminateID = 0; + + const TAiwGenericParam* paramTerminate = + aParams->FindFirst( index, EGenericParamTerminate, EVariantTypeTInt32 ); + + if ( paramTerminate ) + { + paramTerminate->Value().Get( terminateID ); + } + + if ( terminateID ) + { + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::HandleAiwGenericParamListL() Terminate message received")); + + // + // Embedded app is being closed + // + + // + // Workaround. Will handle it once AIW gets supported + // + //iAppUi->HandleCommandL( EEikCmdExit ); + + retVal = KErrCancel; + } + else + { + // + // Determine if these parameters are for PDL + // + index = 0; + TInt32 dlId = KErrNotFound; + + const TAiwGenericParam* genParamDlId = + aParams->FindFirst( index, EGenericParamDownloadId, EVariantTypeTInt32 ); + + if ( genParamDlId ) + { + genParamDlId->Value().Get( dlId ); + + index = 0; + + const TAiwGenericParam* paramFileName = + aParams->FindFirst( index, EGenericParamFile, EVariantTypeDesC ); + + TPtrC fileName; + + // + // Set the filename. The LWPlayerAppUi checks for the + // filename and exits if it doesn't exist + // + fileName.Set( paramFileName->Value().AsDes() ); + + if ( ! iPdlHandler ) + { + iPdlHandler = CMpxVideoEmbeddedPdlHandler::NewL( this ); + } + + iPdlHandler->ConnectToEmbeddedDownloadL( dlId, fileName ); + } + else + { + // + // Check Access Point + // + index = 0; + + const TAiwGenericParam* genParamAccessPoint = + aParams->FindFirst( index, EGenericParamAccessPoint, EVariantTypeTInt32 ); + + if ( index >= 0 && genParamAccessPoint ) + { + TInt32 apId = KErrUnknown; + genParamAccessPoint->Value().Get( apId ); + iExtAccessPointId = apId; + } + } + } + + return retVal; +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::OpenFileL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::OpenFileL( RFile& aFile, const CAiwGenericParamList* aParams ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::OpenFileL(RFile)")); + + TInt err = KErrNone; + + if ( aParams ) + { + err = HandleAiwGenericParamListL( aParams ); + } + + if ( KErrNone == err && ! iPdlHandler ) + { + // + // Create member variables for embedded use cases that are not PDL + // + CreatePlaybackUtilityMemberVariablesL(); + + TFileName filename; + aFile.FullName(filename); + + CMediaRecognizer::TMediaType mediaType = iRecognizer->IdentifyMediaTypeL( filename, aFile ); + + if ( mediaType == CMediaRecognizer::ELocalRamFile || + mediaType == CMediaRecognizer::ELocalAsxFile ) + { + HandleMultiLinksFileL( aFile, mediaType ); + } + else if ( mediaType == CMediaRecognizer::ELocalSdpFile ) + { + SetAccessPointL(); + iPlaybackUtility->InitStreamingL( aFile, iAccessPointId ); + } + else + { + iPlaybackUtility->InitL( aFile ); + } + } + + iRecognizer->FreeFilehandle(); + + aFile.Close(); +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::OpenFileL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::OpenFileL( const TDesC& aFileName ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::OpenFileL()"), + _L("aFileName = %S"), &aFileName); + + // + // Create member variables for embedded use cases that are not PDL + // + CreatePlaybackUtilityMemberVariablesL(); + + CMediaRecognizer::TMediaType mediaType = iRecognizer->IdentifyMediaTypeL(aFileName); + + if ( mediaType == CMediaRecognizer::ELocalVideoFile ) + { + iPlaybackUtility->InitL( aFileName ); + } + // check if aFileName is a path to a ram or asx file + // eg. c:\\data\\videos\\ramfile.ram + else if ( mediaType == CMediaRecognizer::ELocalRamFile || + mediaType == CMediaRecognizer::ELocalAsxFile ) + { + HandleMultiLinksFileL( aFileName, mediaType ); + } + // check if this is a url eg. rtsp://someaddress/file.3gp + // + else if ( iRecognizer->IsValidStreamingPrefix(aFileName) ) + { + HandleUrlDesL( aFileName ); + } + else if ( mediaType == CMediaRecognizer::ELocalSdpFile ) + { + SetAccessPointL(); + iPlaybackUtility->InitStreamingL( aFileName, + (TDesC8*)(&KDATATYPEVIDEOHELIX), + iAccessPointId ); + } + else + { + iPlaybackUtility->InitL( aFileName ); + } + + iRecognizer->FreeFilehandle(); +} + +// ------------------------------------------------------------------------------------------------- +// Open MPX media to player. +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::OpenMediaL( const CMPXMedia& aMedia ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::OpenMediaL()")); + + // Assume MPX medias are always local clips + CMPXCollectionPath* mediaPath = CMPXCollectionPath::NewL(); + CleanupStack::PushL( mediaPath ); + + // + // Workaround. Need a file like vcxmyvideosuids.h + // + mediaPath->AppendL( 0x20016B97 ); + mediaPath->AppendL( KVcxMvcCategoryIdAll ); + + mediaPath->AppendL( aMedia.ValueTObjectL( KMPXMediaGeneralId ) ); + mediaPath->SelectL( aMedia.ValueTObjectL( KMPXMediaGeneralId ) ); + + CMPXCollectionPlaylist* playList = CMPXCollectionPlaylist::NewL( *mediaPath ); + CleanupStack::PushL( playList ); + playList->SetSingleItemPlaylist(); + playList->SetToFirst(); + + CreatePlaybackUtilityMemberVariablesL(); + + iPlaybackUtility->InitL( *playList, ETrue ); + + CleanupStack::PopAndDestroy( playList ); + CleanupStack::PopAndDestroy( mediaPath ); +} + +// ------------------------------------------------------------------------------------------------- +// Handle playback message. +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::DoHandlePlaybackMessageL( const CMPXMessage& aMessage ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::DoHandlePlaybackMessageL()")); + + TMPXMessageId id( *aMessage.Value( KMPXMessageGeneralId ) ); + + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::DoHandlePlaybackMessageL TMPXMessageId = 0x%08x"), id ); + + if ( KMPXMessageGeneral == id ) + { + TInt event( *aMessage.Value( KMPXMessageGeneralEvent ) ); + + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::DoHandlePlaybackMessageL() event = %d"), event); + + switch ( event ) + { + case TMPXPlaybackMessage::EPlayerChanged: + { + MPX_DEBUG(_L(" EPlayerChanged")); + + if ( iUpdateSeekInfo ) + { + // The plugin has been instantiated, update the media + UpdatePbPluginMediaL(); + iUpdateSeekInfo = EFalse; + } + + HandlePlaybackPlayerChangedL(); + break; + } + } + } +} + +// ------------------------------------------------------------------------------------------------- +// Handle playback message for player changed. +// Activate the view which support this player +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandlePlaybackPlayerChangedL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandlePlaybackPlayerChangedL()")); + + MMPXPlayer* player = iPlaybackUtility->PlayerManager().CurrentPlayer(); + + TUid pluginUid( KNullUid ); + RArray array; + + CleanupClosePushL( array ); + + if ( iPdlHandler ) + { + array.AppendL( KVideoPdlPlaybackViewUid ); + } + else + { + if ( player ) + { + pluginUid = player->UidL(); + array.AppendL( pluginUid ); + } + } + + ActivateVideoPlaybackView(); + + CleanupStack::PopAndDestroy( &array ); +} + +// ------------------------------------------------------------------------------------------------- +// Creates plugin resolver + creates & activates the video view +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::ActivateVideoPlaybackView() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::ActivateVideoPlaybackView()")); + + iPlaybackWrapper->openPlaybackView(); +} + +// ------------------------------------------------------------------------------------------------- +// Closed mpx components and readies to application takedown. +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::PrepareCloseMpxL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::PrepareCloseMpxL()")); + + if ( iPlaybackUtility ) + { + iPlaybackUtility->CommandL( EPbCmdClose ); + MMPXPlayerManager& manager = iPlaybackUtility->PlayerManager(); + TRAP_IGNORE( manager.ClearSelectPlayersL() ); + } +} + +// ------------------------------------------------------------------------------------------------- +// Sets AppUiEngine in stand alone "mode" +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::StartStandAloneL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::StartStandAloneL()")); + + // + // Create the utilities for the stand alone player + // + CreatePlaybackUtilityMemberVariablesL(); + + // Fetch the video collection UID + RArray uid; + CleanupClosePushL( uid ); + + uid.AppendL( TUid::Uid( KVcxMediaIdMyVideos ) ); + + iVideoCollectionId = iCollectionUtility->CollectionIDL( uid.Array() ); + + CleanupStack::PopAndDestroy( &uid ); + + // + // Workaround. Don't use mpx view utility yet + // + // iViewUtility->SetAsDefaultViewL( KUidMyVideosViewType ); +} + +// ------------------------------------------------------------------------------------------------- +// Handle collection message +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::DoHandleCollectionMessageL( CMPXMessage* aMessage ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::DoHandleCollectionMessageL()")); + + TMPXMessageId id = *(aMessage->Value( KMPXMessageGeneralId )); + + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::DoHandleCollectionMessageL() TMPXMessageId = 0x%08x"), id ); + + if ( id == KMPXMessageGeneral ) + { + TInt event( *( aMessage->Value ( KMPXMessageGeneralEvent )) ); + TInt type( *( aMessage->Value ( KMPXMessageGeneralType )) ); + TInt data( *( aMessage->Value ( KMPXMessageGeneralData )) ); + + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::DoHandleCollectionMessageL event %d, type %d, data %d"), event, type, data ); + + if ( event == TMPXCollectionMessage::EPathChanged && type == EMcPathChangedByOpen ) + { + if ( data == EMcItemOpened ) + { + // An item was opened on the collection. Get the media attributes + // on the item so we can initiatiate playback + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::DoHandleCollectionMessageL: EMcItemOpened received. Can open video")); + + CMPXCollectionPath* cPath = iCollectionUtility->Collection().PathL(); + + CleanupStack::PushL( cPath ); + + if ( cPath->Count() > 0 ) + { + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::DoHandleCollectionMessageL: Call MediaL() on collection.")); + + RArray attribs; + CleanupClosePushL( attribs ); + + attribs.Append( KMPXMediaGeneralUri ); + attribs.Append( KVcxMediaMyVideosDownloadId ); + iCollectionUtility->Collection().MediaL( *cPath, attribs.Array() ); + + // Create the playlist + // Create proper playlist + // InitPlaybackEngineL( *cPath ); + + CleanupStack::PopAndDestroy( &attribs ); + } + + CleanupStack::PopAndDestroy( cPath ); + } + else if ( data == EMcContainerOpened && iMultilinkPlaylist ) + { + // start the playback for streaming playlists + // once the playlist is opened + iMultilinkPlaylist = EFalse; + + // The playlist was opened, initiatiate playback + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::DoHandleCollectionMessageL: EMcContainerOpened received. initiatiate playback")); + + CMPXCollectionPath* cPath = iCollectionUtility->Collection().PathL(); + CleanupStack::PushL( cPath ); + + if ( cPath->Count() > 0 ) + { + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::DoHandleCollectionMessageL: Call Playback utility with the playlist.")); + + CMPXCollectionPlaylist* playlist = CMPXCollectionPlaylist::NewL( *cPath ); + CleanupStack::PushL( playlist ); + + // Set the AutoPlay mode to false + playlist->SetAutoPlay(EFalse); + // set pre init plugin to false + playlist->SetPreInitPlugin(EFalse); + + iPlaybackUtility->InitL( *playlist, ETrue ); + CleanupStack::PopAndDestroy( playlist ); + } + CleanupStack::PopAndDestroy( cPath ); + } + } + } +} + +// ------------------------------------------------------------------------------------------------- +// From MMPXCollectionObserver. +// Handle media properties. +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::DoHandelCollectionMediaL( const CMPXMedia& aMedia ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::DoHandelCollectionMediaL()")); + + const TDesC& fileUri = aMedia.ValueText(KMPXMediaGeneralUri); + + MPX_DEBUG(_L("Video URI: %S"), &fileUri ); + + if ( aMedia.IsSupported( KVcxMediaMyVideosDownloadId ) && + aMedia.ValueTObjectL( KVcxMediaMyVideosDownloadId ) != 0 ) + { + TUint32 dlId = aMedia.ValueTObjectL( KVcxMediaMyVideosDownloadId ); + + if ( ! iPdlHandler ) + { + iPdlHandler = CMpxVideoEmbeddedPdlHandler::NewL( this ); + } + + iPdlHandler->ConnectToCollectionDownloadL( dlId, const_cast( fileUri ) ); + } + else + { + //OpenMediaL( aMedia ); // Initialize and initiate playback of a single video + + TPtrC mediaFile( aMedia.ValueText( KMPXMediaGeneralUri ) ); + CMediaRecognizer::TMediaType mediaType = iRecognizer->IdentifyMediaTypeL(mediaFile); + + if ( mediaType == CMediaRecognizer::ELocalRamFile || + mediaType == CMediaRecognizer::ELocalAsxFile ) + { + CreatePlaybackUtilityMemberVariablesL(); + + HandleMultiLinksFileL( mediaFile, mediaType ); + } + else + { + OpenMediaL( aMedia ); // Initialize and initiate playback of a single video + } + } +} + +// ------------------------------------------------------------------------------------------------- +// Steps back one level back in collection path. Will activate previous view if level exists +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::StepBackCollectionPathL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::StepBackCollectionPathL()")); + + // Back the collection path one level... + + CMPXCollectionPath* cPath = iCollectionUtility->Collection().PathL(); + CleanupStack::PushL( cPath ); + + // Don't back up if there are no more levels or will panic + if ( cPath->Levels() > 1 ) + { + cPath->Back(); + iCollectionUtility->Collection().OpenL( *cPath ); + + // + // Workaround. Don't use mpx view utility yet + // + // iViewUtility->ActivatePreviousViewL(); + } + + CleanupStack::PopAndDestroy( cPath ); +} + +// ------------------------------------------------------------------------------------------------- +// Initialize the playback engine with a collection path +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::InitPlaybackEngineL( CMPXCollectionPath& aPath ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::InitPlaybackEngineL()")); + + // Create a playlist with the current collection path + CMPXCollectionPlaylist* playlist = CMPXCollectionPlaylist::NewL( aPath ); + CleanupStack::PushL( playlist ); + + playlist->SetSingleItemPlaylist(); + iPlaybackUtility->InitL( *playlist, ETrue ); + + CleanupStack::PopAndDestroy( playlist ); +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::HandleMultiLinksFileL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleMultiLinksFileL( const TDesC& aFileName, + CMediaRecognizer::TMediaType aMediaType ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleMultiLinksFileL()"), + _L("aFileName = %S, type = %d"), &aFileName, aMediaType ); + + TBool singleLink; + TBool localFile; + + CVideoPlaylistUtility* playlistUtil = CVideoPlaylistUtility::NewL(); + CleanupStack::PushL(playlistUtil); + + playlistUtil->GetFileInfoL( aFileName, aMediaType, singleLink, localFile ); + + DoHandleMultiLinksFileL( playlistUtil, singleLink, localFile ); + + CleanupStack::PopAndDestroy( playlistUtil ); +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::HandleMultiLinksFileL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleMultiLinksFileL( RFile& aFile, + CMediaRecognizer::TMediaType aMediaType ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleMultiLinksFileL(RFile)")); + + // playlist + TBool singleLink; + TBool localFile; + + CVideoPlaylistUtility* playlistUtil = CVideoPlaylistUtility::NewL(); + CleanupStack::PushL(playlistUtil); + + playlistUtil->GetFileInfoL( aFile, aMediaType, singleLink, localFile ); + + DoHandleMultiLinksFileL( playlistUtil, singleLink, localFile ); + + CleanupStack::PopAndDestroy( playlistUtil ); +} + + +void CMpxVideoPlayerAppUiEngine::DoHandleMultiLinksFileL( CVideoPlaylistUtility* aPlaylistUtil, + TBool aSingleLink, + TBool aLocalFile ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::DoHandleMultiLinksFileL()"), + _L("aSingleLink = %d aLocalFile %d "), aSingleLink, aLocalFile); + + if ( aSingleLink ) + { + TPtrC link; + link.Set( aPlaylistUtil->GetLinkLC() ); + iUpdateSeekInfo = ETrue; + iSeekable = aPlaylistUtil->IsSeekable(); + + if ( aLocalFile ) + { + CMediaRecognizer::TMediaType mediaType = iRecognizer->IdentifyMediaTypeL( link ); + + if ( mediaType == CMediaRecognizer::EUnidentified ) + { + User::Leave( KErrNotSupported ); + } + else + { + iPlaybackUtility->InitL( link ); + } + } + else + { + SetAccessPointL(); + iPlaybackUtility->InitStreamingL( link, + (TDesC8*)(&KDATATYPEVIDEOHELIX), + iAccessPointId ); + } + CleanupStack::PopAndDestroy(); // link + } + else + { + if ( ! aLocalFile ) + { + SetAccessPointL(); + } + + CMPXMedia* playlist = aPlaylistUtil->GetPlayListL( iAccessPointId ); + CleanupStack::PushL( playlist ); + + // Create FW utility member variables for playlist embedded use case + CreateCollectionUtilityMemberVariablesL(); + + // Set the flag to true + iMultilinkPlaylist = ETrue; + + // load the in memory plugin + iCollectionUiHelper->OpenL( KUidMpxVideoPlayerApplication, + *playlist, + this, + EMPXCollectionPluginGallery ); + + CleanupStack::PopAndDestroy( playlist ); + } +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::HandleUrlDesL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleUrlDesL( const TDesC& aUrl ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleUrlDesL()"), + _L("aUrl = %S"), &aUrl ); + + SetAccessPointL(); + + iPlaybackUtility->InitStreamingL( aUrl, + (TDesC8*)(&KDATATYPEVIDEOHELIX), + iAccessPointId ); +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::SetAccessPointL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::SetAccessPointL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::SetAccessPointL()")); + + // a value was passed in for argument aAPId + if ( ( iExtAccessPointId != KErrUnknown ) && IsWLANAccessPointL( iExtAccessPointId ) ) + { + // if the external AP(passed in by an embedding app) + // is a WLAN AP - it must be used + iAccessPointId = iExtAccessPointId; + } + else + { + // attempt to read the default AP + TInt defaultAPId(0); + + MPX_TRAPD( err, defaultAPId = GetDefaultAccessPointL() ); + + if ( (err == KErrNone) && (defaultAPId != 0)) + { + // a valid default AP has been read and should be used + iAccessPointId = defaultAPId; + } + else + { + // a valid AP was NOT read ... + + if (iExtAccessPointId != KErrUnknown) + { + // use the AP passed in by embedding app, regardless of bearer type + iAccessPointId = iExtAccessPointId; + } + else + { + // open the Access Point selection dialog and make a selection + TUint32 apUid = SelectAPFromListL(); + + // if the user actually selected an AP from the dialog + // i.e. the user did not "cancel" the dialog + if ( apUid != 0 ) + { + // convert the AccessPoint-Uid to AccessPoint-Id + iAccessPointId = GetAccessPointIdForUIDL(apUid); + } + } + } + } +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::IsWLANAccessPointL +// ------------------------------------------------------------------------------------------------- +// +TBool CMpxVideoPlayerAppUiEngine::IsWLANAccessPointL( TInt aAPId ) +{ + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::IsWLANAccessPointL(%d)"), aAPId); + + TBool wlanAP(EFalse); + + TApBearerType apBearerType = EApBearerTypeAllBearers; + + CCommsDatabase* commsDb = CCommsDatabase::NewL( EDatabaseTypeIAP ); + CleanupStack::PushL( commsDb ); + + CApUtils* apUtils = CApUtils::NewLC( *commsDb ); + + // in case there's some reserved IAP (i.e. DVB-H), which can potentially cause + // a mismatch between WAP ID and IAP ID database, we should always + // check to get the correct WAP record ID for a given IAP record ID + // before we obtain the bearer type + + MPX_TRAPD( err, + { + TInt32 wapId = apUtils->WapIdFromIapIdL( aAPId ); + apBearerType = apUtils->BearerTypeL( wapId ); + } ); + + CleanupStack::PopAndDestroy(2); // apUtils, commsDb + + // + // Only use AP passed in if it's of WLAN bearer type + // This method is being called only for Embedded. + // + if ( ! err && apBearerType == EApBearerTypeWLAN) + { + wlanAP = ETrue; + } + + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::IsWLANAccessPointL() return %d"), wlanAP); + + return wlanAP; +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::GetDefaultAccessPointL +// ------------------------------------------------------------------------------------------------- +// +TInt CMpxVideoPlayerAppUiEngine::GetDefaultAccessPointL() +{ + TInt defaultAP(0); + TUint32 iap; + + CMPSettingsModel* ropSettings = CMPSettingsModel::NewL( KSettingsModelForROPUid ); + + CleanupStack::PushL( ropSettings ); + + ropSettings->LoadSettingsL( EConfigDefault ); + + User::LeaveIfError( ropSettings->GetDefaultAp( iap ) ); + + CleanupStack::PopAndDestroy(); // ropSettings + + defaultAP = GetAccessPointIdForUIDL( iap ); + + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::GetDefaultAccessPointL(%d)"), defaultAP); + + return defaultAP; +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::GetAccessPointIdForUIDL +// ------------------------------------------------------------------------------------------------- +// +TInt CMpxVideoPlayerAppUiEngine::GetAccessPointIdForUIDL( TUint32 aAPUid ) +{ + TInt apId(0); + + CCommsDatabase* commsDb = CCommsDatabase::NewL( EDatabaseTypeIAP ); + CleanupStack::PushL( commsDb ); + + CApUtils* apUtils = CApUtils::NewLC( *commsDb ); + + apId = static_cast( apUtils->IapIdFromWapIdL( aAPUid ) ); + + CleanupStack::PopAndDestroy(2); // apUtils, commsDb + + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::GetAccessPointIdForUIDL(%d)"), apId); + + return apId; +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::SelectAPFromListL +// ------------------------------------------------------------------------------------------------- +// +TUint32 CMpxVideoPlayerAppUiEngine::SelectAPFromListL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::SelectAPFromListL()")); + + TUint32 apUid(0); + TUint32 returnVal(0); + + CApSettingsHandler* dlg = + CApSettingsHandler::NewLC( ETrue, + EApSettingsSelListIsPopUp, + EApSettingsSelMenuSelectNormal, + KEApIspTypeAll, + EApBearerTypeAll, + KEApSortNameAscending, + EIPv4 | EIPv6 ); + + if ( dlg->RunSettingsL( iAccessPointId, apUid ) ) + { + if ( apUid > 0 ) + { + returnVal = apUid; + } + } + + if ( apUid <= 0 ) + { + User::Leave( KErrCancel ); + } + + CleanupStack::PopAndDestroy( dlg ); + + return returnVal; +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::ProcessActivationMessageL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::ProcessActivationMessageL( const TDesC8 &aMsg ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::ProcessActivationMessageL()")); + + if ( aMsg.Length() < KVideoPlayerActivationMessageMinLength ) + { + User::Leave( KErrNotSupported ); + } + + TVideoPlayerActivationMessage msgHandler; + TPckg paramsPckg( msgHandler ); + paramsPckg.Copy( aMsg ); + + /*if ( msgHandler.iMsgSender == TVideoPlayerActivationMessage::EMatrixMenu ) + { + // Clear the view history, so app exits back to matrix. + iViewUtility->PushDefaultHistoryL(); + } + + if ( msgHandler.iMsgType == TVideoPlayerActivationMessage::EOpenInternetVideos ) + { + iViewUtility->ActivateViewL( TUid::Uid( KMpxVideoPlayerVodViewPluginTypeId ) ); + } + else if ( msgHandler.iMsgType == TVideoPlayerActivationMessage::EOpenVideoStorage ) + { + iViewUtility->ActivateViewL( TUid::Uid( KUidMyVideosViewTypeId ) ); + } + else*/ if ( msgHandler.iMsgType == TVideoPlayerActivationMessage::ELaunchVideoToPlayer ) + { + // Launch video to player, it can be either local video or stream. + + // If there's path and mpx id, + // clip can be played directly. + if ( msgHandler.iServiceId && + msgHandler.iFullPath.Length() > 0 ) + { + if ( iRecognizer->IdentifyMediaTypeL( msgHandler.iFullPath ) + == CMediaRecognizer::ELocalVideoFile ) + { + TMPXItemId id; + id.iId1 = msgHandler.iServiceId; + CMPXMedia* media = CMPXMedia::NewL(); + CleanupStack::PushL( media ); + media->SetTObjectValueL( KMPXMediaGeneralId, id ); + OpenMediaL( *media ); + CleanupStack::PopAndDestroy( media ); + } + else + { + // Most likely the clip has been deleted + User::Leave( KErrNotFound ); + } + } + } + /*else + { + TBool vodUiRunning = ( iViewUtility->ActiveViewType() == + TUid::Uid( KMpxVideoPlayerVodViewPluginTypeId ) ); + + if ( vodUiRunning ) + { + // VOD is active, must use the utility to pass the message. + // Workaround for a test stopper, to be refactored. + CVcxViewMessageUtility::InstanceL()->SendCustomViewMessageL( TUid::Uid(0), aMsg ); + } + else + { + // VOD is not running, activate with custom message. + HBufC* customMsg = HBufC::NewLC( paramsPckg.Length() ); + customMsg->Des().Copy( paramsPckg ); + iViewUtility->ActivateViewL( TUid::Uid( KMpxVideoPlayerVodViewPluginTypeId ), customMsg ); + CleanupStack::PopAndDestroy( customMsg ); + + // Clear the view history, so playback returns where it was started + iViewUtility->PushDefaultHistoryL(); + } + } + } + else if ( msgHandler.iMsgType == TVideoPlayerActivationMessage::ELaunchServiceById ) + { + if ( iViewUtility->ActiveViewType() == TUid::Uid( KMpxVideoPlayerVodViewPluginTypeId ) ) + { + // VOD is active, must use the utility to pass the message. + // Workaround for a test stopper, to be refactored. + CVcxViewMessageUtility::InstanceL()->SendCustomViewMessageL( TUid::Uid(0), aMsg ); + } + else + { + // VOD is not running, activate with custom message. + HBufC* customMsg = HBufC::NewLC( paramsPckg.Length() ); + customMsg->Des().Copy( paramsPckg ); + iViewUtility->ActivateViewL( TUid::Uid( KMpxVideoPlayerVodViewPluginTypeId ), customMsg ); + CleanupStack::PopAndDestroy( customMsg ); + } + }*/ +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::HandleMessageL() +// ------------------------------------------------------------------------------------------------- +// +TBool CMpxVideoPlayerAppUiEngine::HandleMessageL( TUid aMessageUid, + const TDesC8& aMessageParameters ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleMessageL()")); + + TBool msgHandled = EFalse; + + switch ( aMessageUid.iUid ) + { + // TVideoPlayerActivationMessage received. + case KVideoPlayerVodStartPlayer: + { + ProcessActivationMessageL( aMessageParameters ); + msgHandled = ETrue; + break; + } + case KVideoPlayerStartPDlPlayer: + { + // Start the PDl + if ( iPdlHandler ) + { + CBufFlat* paramBuf = CBufFlat::NewL( 1 ); + CleanupStack::PushL( paramBuf ); + paramBuf->InsertL( 0, aMessageParameters ); + RBufReadStream readStream( *paramBuf ); + + CAiwGenericParamList* genParamList = CAiwGenericParamList::NewLC( readStream ); + + HandleAiwGenericParamListL( genParamList ); + + CleanupStack::PopAndDestroy( genParamList ); + CleanupStack::PopAndDestroy( paramBuf ); + + msgHandled = ETrue; + } + + break; + } + } + + return msgHandled; +} + +// ------------------------------------------------------------------------------------------------- +// Handle Custom messages from the collection +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleCollectionMessage( CMPXMessage* aMessage, TInt aError ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleCollectionMessage()")); + + if ( aError == KErrNone && aMessage ) + { + TRAP_IGNORE( DoHandleCollectionMessageL( aMessage ) ) + } +} + +// ------------------------------------------------------------------------------------------------- +// From MMPXCollectionObserver. +// Handle media properties. +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleCollectionMediaL( const CMPXMedia& aMedia, TInt aError ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleCollectionMediaL()")); + + if ( aError == KErrNone ) + { + DoHandelCollectionMediaL( aMedia ); + } +} + +// ------------------------------------------------------------------------------------------------- +// From MMPXCollectionObserver. +// Handles the collection entries being opened. +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleOpenL( const CMPXMedia& /* aEntries */, + TInt /* aIndex */, + TBool /* aComplete */, + TInt aError ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleOpenL(CMPXMedia)")); + + if ( aError != KErrNone ) + { + // + // Clip the collection path to root level and reopen + // This could happen after a USB refresh event where the + // item no longer exists + // + CMPXCollectionPath* path = iCollectionUtility->Collection().PathL(); + + CleanupStack::PushL( path ); + + while( path->Levels() > 1 ) + { + path->Back(); + } + + iCollectionUtility->Collection().OpenL( *path ); + CleanupStack::PopAndDestroy( path ); + } +} + +// ------------------------------------------------------------------------------------------------- +// From MMPXCollectionObserver. +// Handles the item being opened. +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleOpenL( const CMPXCollectionPlaylist& aPlaylist, TInt aError ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleOpenL(CMPXCollectionPlaylist)")); + + if ( aError == KErrNone ) + { + iPlaybackUtility->InitL( aPlaylist, EFalse ); + } +} + + + +// ------------------------------------------------------------------------------------------------- +// From MMPXCHelperEmbeddedOpenObserver +// Handles OpenL from that occured in embedded mode +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::HandleEmbeddedOpenL( TInt aErr, TMPXGeneralCategory /*aCategory*/ ) +{ + MPX_DEBUG(_L("CMPXVideoAppUi::HandleEmbeddedOpenL()")); + + if ( aErr != KErrNone ) + { + + // Kill MPX + //RunAppShutter(); + } + else // No error, set the launch mode + { + iPlaybackUtility->CommandL( EPbCmdDisableEffect ); + } +} + + +void CMpxVideoPlayerAppUiEngine::HandleSoftKeyBackL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::HandleSoftKeyBackL()")); + + // + // if we're in top level of our local view stack, + // back command exits the app. otherwise activate + // the previous view in our local view stack + // + + // + // Workaround. Don't use mpx view utility yet + // + // if ( iViewUtility->ViewHistoryDepth() <= 1 ) + if ( ETrue ) + { + ActivateExitActiveObject(); + } + else + { + StepBackCollectionPathL(); + } +} + +TBool CMpxVideoPlayerAppUiEngine::ProcessCommandParametersL( TApaCommand aCommand, + TFileName& aDocumentName, + const TDesC8& aTail ) +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::ProcessCommandParametersL()")); + + TBool retVal = EFalse; + + // + // If command line has tail, this is probably a message from Matrix, Live TV + // reminder, Video Center soft notification, or other VC component. + // + if ( aTail.Length() > 0 ) + { + ProcessActivationMessageL( aTail ); + } + else + { + // + // If we are embedded or the command is to open a document + // + + // + // Workaround. Embedded doesn't work yet + // + // if ( iAppUi->IsEmbedded() || aCommand != EApaCommandRun ) + if ( aCommand != EApaCommandRun ) + { + if ( iRecognizer->IsValidStreamingPrefix( aDocumentName ) ) + { + retVal = ETrue; + } + else + { + retVal = ConeUtils::FileExists( aDocumentName ); + } + } + else + { + StartStandAloneL(); + } + } + + return retVal; +} + +void CMpxVideoPlayerAppUiEngine::ActivateExitActiveObject() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::ActivateExitActiveObject()")); + + if ( ! iExitAo->IsActive() ) + { + iExitAo->Start( TCallBack( CMpxVideoPlayerAppUiEngine::ExitApplicationL, this ) ); + } +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::ExitApplicationL +// ------------------------------------------------------------------------------------------------- +// +TInt CMpxVideoPlayerAppUiEngine::ExitApplicationL( TAny* aPtr ) +{ + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::ExitApplicationL()")); + + static_cast(aPtr)->DoExitApplicationL(); + return KErrNone; +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::DoExitApplicationL +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::DoExitApplicationL() +{ + MPX_ENTER_EXIT(_L("CMpxVideoPlayerAppUiEngine::DoExitApplicationL()")); + + /*iAppUi->HandleCommandL( EEikCmdExit );*/ +} + +// ------------------------------------------------------------------------------------------------- +// CMpxVideoPlayerAppUiEngine::UpdatePbPluginMedia() +// ------------------------------------------------------------------------------------------------- +// +void CMpxVideoPlayerAppUiEngine::UpdatePbPluginMediaL() +{ + MPX_DEBUG(_L("CMpxVideoPlayerAppUiEngine::UpdatePbPluginMediaL()iSeekable %d"), iSeekable); + + CMPXCommand* cmd = CMPXCommand::NewL(); + CleanupStack::PushL( cmd ); + + cmd->SetTObjectValueL( KMPXCommandGeneralDoSync, ETrue ); + + cmd->SetTObjectValueL( KMPXCommandGeneralId, KMPXMediaIdVideoPlayback ); + + cmd->SetTObjectValueL( KMPXMediaVideoPlaybackCommand, + EPbCmdUpdateSeekable ); + + cmd->SetTObjectValueL( KMPXMediaGeneralExtVideoSeekable, iSeekable ); + + iPlaybackUtility->CommandL( *cmd ); + + CleanupStack::PopAndDestroy( cmd ); +} + +// EOF +