photosgallery/viewframework/commandhandlers/commandhandlerupnp/src/glxupnprendererimpl.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/photosgallery/viewframework/commandhandlers/commandhandlerupnp/src/glxupnprendererimpl.cpp Thu Dec 17 08:45:44 2009 +0200
@@ -0,0 +1,557 @@
+/*
+* Copyright (c) 2008-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: Implements rendering of the Image/Video
+*
+*/
+
+
+
+
+#include "glxupnprendererimpl.h"
+
+#include <glxattributecontext.h> // CGlxAttributeContext
+#include <glxattributeretriever.h> // CGlxAttributeRetriever
+#include <glxuiutility.h> // CGlxUiUtility
+#include <glxtracer.h>
+#include <glxlog.h> // GLX_LOG
+#include <glxmedialist.h> // CGlxMediaList
+#include <glxthumbnailattributeinfo.h> // KGlxMediaIdThumbnail
+#include <glxthumbnailcontext.h> // CGlxThumbnailContext
+#include <glxuistd.h> // Fetch context priority def'ns
+#include <glxerrormanager.h> // GlxErrorManager
+#include <glxmedia.h> // TGlxMedia
+#include "glxupnprenderer.h"
+// CONSTANTS
+const TInt KVideoIconThumbnailWidth = 640;
+const TInt KVideoIconThumbnailHeight = 480;
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+CGlxUpnpRendererImpl* CGlxUpnpRendererImpl::NewL()
+ {
+ TRACER("CGlxUpnpRendererImpl::NewL()");
+
+ CGlxUpnpRendererImpl* self = new(ELeave) CGlxUpnpRendererImpl;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+//---------------------------------------------------------------------------------
+// Defalut Constructor
+//---------------------------------------------------------------------------------
+CGlxUpnpRendererImpl::CGlxUpnpRendererImpl()
+ {
+ //Do Nothing
+ }
+
+//---------------------------------------------------------------------------------
+// 2nd phase Constructor
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::ConstructL()
+ {
+ TRACER("CGlxUpnpRendererImpl::ConstructL()");
+
+ // Create the asynchronous callback for focus changes
+ iHandleFocusChangeCallback = new ( ELeave )
+ CAsyncCallBack( TCallBack( DoFocusChanged, this ),
+ CActive::EPriorityStandard );
+
+ //Create the showcommand to query the upnpframework
+ iUpnpShowCommand = CUpnpShowCommand::NewL(this);
+
+
+ if(iUpnpShowCommand)
+ {
+ iUpnpSupported = ETrue;
+ }
+ //Allocate the UPNP resources to show the Image/Video
+ if(iUpnpSupported)
+ {
+ iUpnpShowCommand->StartShowingL();
+ }
+
+ iUpnpErrorStatus = NGlxUpnpRenderer::EUpnpKErrNone;
+ PrepareMediaListL();
+
+ }
+
+//---------------------------------------------------------------------------------
+// Destructor
+//---------------------------------------------------------------------------------
+CGlxUpnpRendererImpl::~CGlxUpnpRendererImpl()
+ {
+ TRACER("CGlxUpnpRendererImpl::~CGlxUpnpRendererImpl()");
+
+ // delete also cancels the callback
+ delete iHandleFocusChangeCallback;
+
+ if ( iActiveMediaList ) //cleanup the current list
+ {
+ iActiveMediaList->RemoveMediaListObserver(this);
+ iActiveMediaList->RemoveContext( iAttributeContext );
+ iActiveMediaList->RemoveContext( iThumbnailContext );
+ }
+ if (iActiveMediaListResolver)
+ {
+ iActiveMediaListResolver->Close( this );
+ }
+ delete iAttributeContext;
+
+ delete iThumbnailContext;
+
+ delete iThumbnailSaver;
+
+ if( iUpnpShowCommand )
+ {
+ //To check if we can delete the showcommand without StopShowing
+ TRAP_IGNORE(iUpnpShowCommand->StopShowingL ( ) );
+ delete iUpnpShowCommand;
+ }
+ }
+
+
+//---------------------------------------------------------------------------------
+// If the access point is defined
+//---------------------------------------------------------------------------------
+TBool CGlxUpnpRendererImpl::IsSupported()
+ {
+ TRACER("CGlxUpnpRendererImpl::IsSupported()");
+
+ TInt isSupported = EFalse;
+ //need to trap as we cannot leave
+
+ TRAP_IGNORE( isSupported = CUpnpShowCommand::IsAvailableL ( ) );
+
+ return isSupported;
+ }
+//---------------------------------------------------------------------------------
+// Error Status when Show Image/Video
+//---------------------------------------------------------------------------------
+NGlxUpnpRenderer::TErrorStatus CGlxUpnpRendererImpl::UpnpErrorStatus()
+ {
+ TRACER("CGlxUpnpRendererImpl::UpnpErrorStatus()");
+
+ //The UPnP Show Image/Video error status after the Show request to UPnP Framework
+ return iUpnpErrorStatus;
+ }
+
+//---------------------------------------------------------------------------------
+// Show the Video after a user action
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::UpnpShowVideoL()
+ {
+ TRACER("CGlxUpnpRendererImpl::UpnpShowVideoL");
+ User::LeaveIfError( GlxAttributeRetriever::RetrieveL ( *iAttributeContext,*iActiveMediaList ) );
+
+ if(iUpnpSupported)
+ {
+ const TDesC& videoUri = iActiveMediaList->Item( iActiveMediaList->FocusIndex() ).Uri();
+ iUpnpShowCommand->ShowVideoL( videoUri );
+ }
+
+ iIsVideoShow = ETrue;
+ //Hiding the HUI display,so that the UPnPFw will take the
+ //view control and update the view for a video
+ CGlxUiUtility::HideAlfDisplayL();
+ }
+
+//---------------------------------------------------------------------------------
+// Preare the media list
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::PrepareMediaListL()
+ {
+ TRACER("CGlxUpnpRendererImpl::PrepareMediaListL");
+
+ if ( !iActiveMediaListResolver ) //get the singleton instance for the resolver
+ {
+ iActiveMediaListResolver= MGlxActiveMediaListResolver::InstanceL( this );
+ }
+ iActiveMediaList= iActiveMediaListResolver->ActiveMediaList(); //get the currently active medialist
+
+ if ( iActiveMediaList )
+ {
+ CreateContextL();
+ iActiveMediaList->AddContextL( iAttributeContext,
+ KGlxFetchContextPriorityNormal );
+ iActiveMediaList->AddContextL( iThumbnailContext,
+ KGlxFetchContextPriorityNormal );
+ iActiveMediaList->AddMediaListObserverL(this);
+ }
+ }
+
+
+//---------------------------------------------------------------------------------
+// Create the context for the medialist
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::CreateContextL()
+ {
+ TRACER("CGlxUpnpRendererImpl::CreateContextL");
+
+ iAttributeContext = CGlxDefaultAttributeContext::NewL( );
+ iAttributeContext->AddAttributeL( KMPXMediaGeneralUri );
+
+ iThumbnailContext = CGlxDefaultThumbnailContext::NewL( ); // set the thumbnail context
+ iThumbnailContext->SetDefaultSpec( KVideoIconThumbnailWidth, KVideoIconThumbnailHeight ); // 640 pixels wide and 480 pixel height-VGA.
+ }
+
+//---------------------------------------------------------------------------------
+// media object item added
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::HandleItemAddedL(TInt /*aStartIndex*/, TInt /*aEndIndex*/,MGlxMediaList* /*aList*/)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleItemAddedL");
+ }
+
+//---------------------------------------------------------------------------------
+// media object is now available for an item
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::HandleMediaL(TInt /*aListIndex*/, MGlxMediaList* /*aList*/)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleItemAddedL");
+ }
+
+//---------------------------------------------------------------------------------
+// media item was removed from the list
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::HandleItemRemovedL(TInt /*aStartIndex*/, TInt /*aEndIndex*/,MGlxMediaList* /*aList*/)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleItemAddedL");
+ }
+
+//---------------------------------------------------------------------------------
+// Media item was changed
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::HandleItemModifiedL(const RArray<TInt>& /*aItemIndexes*/, MGlxMediaList* /*aList*/)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleItemAddedL");
+ }
+
+//---------------------------------------------------------------------------------
+// Attribute is available
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::HandleAttributesAvailableL(TInt aItemIndex,const RArray<TMPXAttribute>& aAttributes,
+ MGlxMediaList* /*aList*/)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleAttributesAvailableL");
+
+ if ( aItemIndex == iActiveMediaList->FocusIndex() )
+ {
+ SendFocusedItemL(aItemIndex,aAttributes);
+ }
+ }
+
+//---------------------------------------------------------------------------------
+// Focus has moved
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::HandleFocusChangedL(
+ NGlxListDefs::TFocusChangeType /*aType*/, TInt /*aNewIndex*/,
+ TInt /*aOldIndex*/, MGlxMediaList* /*aList*/)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleFocusChangedL");
+ // fix for ERBS-7CFCJE, make focus change handling asynchronous to prevent
+ // UPnP from blocking our garbage collection if the UPnP framework
+ // displays a dialog (e.g. when showing a DRM-protected item).
+ if ( iHandleFocusChangeCallback->IsActive() )
+ {
+ iHandleFocusChangeCallback->Cancel();
+ }
+ iHandleFocusChangeCallback->CallBack();
+ }
+
+//---------------------------------------------------------------------------------
+// Item has been selected
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::HandleItemSelectedL(TInt /*aIndex*/, TBool /*aSelected*/, MGlxMediaList* /*aList*/)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleItemAddedL");
+ }
+
+//---------------------------------------------------------------------------------
+// Notification from the collection
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::HandleMessageL(const CMPXMessage& /*aMessage*/, MGlxMediaList* /*aList*/)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleItemAddedL");
+ }
+
+
+//From MGlxActiveMediaListChangeObserver
+//---------------------------------------------------------------------------------
+// Active media list pointer has changed.
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::HandleActiveMediaListChanged()
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleActiveMediaListChanged()");
+
+ if ( iActiveMediaList ) //cleanup the current list
+ {
+ iActiveMediaList->RemoveMediaListObserver( this );
+ iActiveMediaList->RemoveContext( iAttributeContext );
+ iActiveMediaList->RemoveContext( iThumbnailContext );
+ }
+ TRAP_IGNORE(PrepareMediaListL()); // will give a new list
+ }
+
+
+//From MUpnpCommandObserver
+//---------------------------------------------------------------------------------
+// Show Command has been completed.
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::CommandComplete( TInt aStatusCode )
+ {
+ TRACER("CGlxUpnpRendererImpl::CommandComplete");
+
+ TRAP_IGNORE( CommandCompleteL(aStatusCode) );
+ }
+
+
+//---------------------------------------------------------------------------------
+// Show Command has been completed.
+//---------------------------------------------------------------------------------
+//
+void CGlxUpnpRendererImpl::CommandCompleteL( TInt aStatusCode )
+ {
+ TRACER("CGlxUpnpRendererImpl::CommandCompleteL");
+
+ if( KErrNone == aStatusCode )
+ {
+ GLX_LOG_INFO("Error code is KErrNone");
+ iUpnpErrorStatus = NGlxUpnpRenderer::EUpnpKErrNone;
+ }
+
+ else if( KErrDisconnected == aStatusCode )
+ {
+ GLX_LOG_INFO("Error code is KErrDisconnected");
+ iUpnpErrorStatus = NGlxUpnpRenderer::EUpnpKErrDisconnected;
+
+ iIsVideoShow = EFalse;
+
+ //Show the HUI display
+ CGlxUiUtility::ShowAlfDisplayL();
+
+ // Send state changed command
+ GlxUpnpRenderer::ChangeCommandStateL();
+ }
+
+ if(iUpnpSupported)
+ {
+ if( KUpnpCommandStatusStartPlayVideo == aStatusCode )
+ {
+ GLX_LOG_INFO("KUpnpCommandStatusStartPlayVideo");
+ // Photos hiding their UI
+ CGlxUiUtility::HideAlfDisplayL();
+ }
+ }
+
+ //Check if the show on the rendering device was a video
+ else if( ( iIsVideoShow ) && ( GlxUpnpRenderer::Status() == NGlxUpnpRenderer::EActive ) )
+ {
+ GLX_LOG_INFO("Video play is complete");
+ //Need to trap as we cannot leave
+ ShowImageAfterVideoL();
+ }
+ }
+
+//---------------------------------------------------------------------------------
+// Display the Image after the Video play is Complete
+//---------------------------------------------------------------------------------
+ void CGlxUpnpRendererImpl::ShowImageAfterVideoL()
+ {
+ TRACER("CGlxUpnpRendererImpl::ShowVideoComplete");
+
+ //Show the HUI display once the video play is completed
+ CGlxUiUtility::ShowAlfDisplayL();
+
+ if(iUpnpSupported)
+ {
+ iUpnpShowCommand->ShowImageL( iVideoThumbnail );
+ }
+
+ iIsVideoShow = EFalse;
+ }
+
+
+//From MGlxThumbnailSaveComplete
+//---------------------------------------------------------------------------------
+// Call back for thumbnail save completion
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::HandleFileSaveCompleteL(const TDesC& aPath)
+ {
+ TRACER("CGlxUpnpRendererImpl::HandleFileSaveCompleteL");
+
+ iVideoThumbnail.Copy( aPath );
+
+ if(iUpnpSupported)
+ {
+ iUpnpShowCommand->ShowImageL( iVideoThumbnail );
+ }
+ }
+
+//---------------------------------------------------------------------------------
+// Send the focussed item to the device
+//---------------------------------------------------------------------------------
+
+void CGlxUpnpRendererImpl::SendFocusedItemL(TInt aNewIndex)
+ {
+ TRACER("CGlxUpnpRendererImpl::SendFocusedItemL");
+
+ if(KErrNotFound!=aNewIndex)
+ {
+ const TGlxMedia& item = iActiveMediaList->Item(aNewIndex);
+ TMPXAttribute attrThumb(KGlxMediaIdThumbnail,
+ GlxFullThumbnailAttributeId(ETrue, KVideoIconThumbnailWidth, KVideoIconThumbnailHeight));
+ if ( (iActiveMediaList) && (!item.IsStatic()) )
+ {
+ if( item.Uri().Length() > 0)
+ {
+ GetImageL(item);
+ GetVideoL(item,attrThumb);
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------------------------------
+// Send the focussed item to the device
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::SendFocusedItemL(TInt aNewIndex,const RArray<TMPXAttribute>& aAttributes)
+ {
+ TRACER("CGlxUpnpRendererImpl::SendFocusedItemL");
+
+ if( KErrNotFound != aNewIndex )
+ {
+ const TGlxMedia& item = iActiveMediaList->Item(aNewIndex);
+ TMPXAttribute attrThumb(KGlxMediaIdThumbnail,
+ GlxFullThumbnailAttributeId(ETrue, KVideoIconThumbnailWidth, KVideoIconThumbnailHeight));
+
+ // Loop untill it checks for all the avialable attributes
+ for ( TInt i = aAttributes.Count() - 1; i >= 0 ; i-- )
+ {
+ if ( (iActiveMediaList) && (!item.IsStatic()) )
+ {
+ if( item.Uri().Length() > 0)
+ {
+ //retrive the attribute for showing image
+ if( EMPXImage == item.Category())
+ {
+ GetImageL(item);
+ }
+ //retrive the attribute for showing Video
+ else if ( EMPXVideo == item.Category() )
+ {
+ GetVideoL(item,attrThumb);
+ }
+ }
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------------------------------
+// Get the image attribute
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::GetImageL(const TGlxMedia& aMedia)
+ {
+ TRACER("CGlxUpnpRendererImpl::GetImageL");
+ //retrive the attribute for showing image
+ const CGlxMedia* item = aMedia.Properties();
+ if(EMPXImage == aMedia.Category())
+ {
+ if (!iThumbnailSaver)
+ {
+ iThumbnailSaver=CGlxThumbnailSaver::NewL( this );
+ }
+ if((GlxErrorManager::HasAttributeErrorL(item, KGlxMediaIdThumbnail) != KErrNone))
+ {
+ iThumbnailSaver->CreateDefaultImageIconL();
+ }
+ if ((iPreviouslySentMediaId != aMedia.Id( ) ) )
+ {
+ iPreviouslySentMediaId=aMedia.Id();
+ //show the image Via upnp device
+ if(iUpnpSupported)
+ {
+ const TDesC& imageUri = aMedia.Uri();
+ iUpnpShowCommand->ShowImageL( imageUri );
+ }
+ }
+ }
+ }
+
+//---------------------------------------------------------------------------------
+// Get the video attribute
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::GetVideoL(const TGlxMedia& aMedia,TMPXAttribute& aAttrThumbnail)
+ {
+ TRACER("CGlxUpnpRendererImpl::GetVideoL");
+ const CGlxMedia* item = aMedia.Properties();
+ if(EMPXVideo == aMedia.Category())
+ {
+ if (!iThumbnailSaver)
+ {
+ iThumbnailSaver=CGlxThumbnailSaver::NewL( this );
+ }
+
+ if ( ( aMedia.ThumbnailAttribute( aAttrThumbnail ) )
+ && ( iPreviouslySentMediaId!=aMedia.Id( )) )
+ {
+ iPreviouslySentMediaId=aMedia.Id();
+ //get the thumbnail image
+ const CGlxThumbnailAttribute* value = aMedia.ThumbnailAttribute( aAttrThumbnail );
+ iThumbnailSaver->CreateVideoIconL( value->iBitmap );
+ }
+ else if ((GlxErrorManager::HasAttributeErrorL(item, KGlxMediaIdThumbnail) != KErrNone))
+ {
+ // send the default thumbnail
+ iThumbnailSaver->CreateDefaultVideoIconL();
+ }
+ }
+ }
+
+//---------------------------------------------------------------------------------
+// DoFocusChanged callback
+//---------------------------------------------------------------------------------
+TInt CGlxUpnpRendererImpl::DoFocusChanged( TAny* aPtr )
+ {
+ TRACER("CGlxUpnpRendererImpl::DoFocusChanged");
+
+ CGlxUpnpRendererImpl* self
+ = reinterpret_cast< CGlxUpnpRendererImpl* >( aPtr );
+ TRAP_IGNORE( self->DoFocusChangedL() );
+
+ return 0;
+ }
+
+//---------------------------------------------------------------------------------
+// DoFocusChangedL
+//---------------------------------------------------------------------------------
+void CGlxUpnpRendererImpl::DoFocusChangedL()
+ {
+ // SendFocusedItemL validates the index so no need to do it here too
+ TInt index = iActiveMediaList->FocusIndex();
+ SendFocusedItemL( index );
+ }