upnpframework/upnpmusicadapter/src/upnpalbumservices.cpp
changeset 0 7f85d04be362
child 30 5ec426854821
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpframework/upnpmusicadapter/src/upnpalbumservices.cpp	Thu Dec 17 08:52:00 2009 +0200
@@ -0,0 +1,628 @@
+/*
+* Copyright (c) 2006-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:  provides album handling services for UPnP framework
+*
+*/
+
+#include "upnpapplicationcrkeys.h" // KCRUidUPnPApplication
+#include <mpxcollectionutility.h>
+#include <mpxcollectionframeworkdefs.h> // main attribute keys
+#include <mpxmessagegeneraldefs.h>
+#include <mpxmediageneraldefs.h> // commonly used attribute keys
+#include <mpxmediacontainerdefs.h> // container-specific attribute keys
+#include <mpxcollectionpath.h>
+#include <mpxcollectionmessage.h>
+#include <mpxmediadrmdefs.h>
+
+#include <mpxmedia.h>
+#include <mpxmediaarray.h>
+
+#include "upnpalbumservices.h" // ourselves
+
+// debug
+_LIT16( KComponentLogfile, "musicadapter.txt" );
+#include "upnplog.h"
+
+// Constant definitions
+#define KAlbumsCollectionUid 0x20007197 // album plugin uid
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CUPnPAlbumServices::NewL
+// 1st phase constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CUPnPAlbumServices* CUPnPAlbumServices::NewL()
+    {
+    __LOG( "CUPnPAlbumServices::NewL" );
+
+    CUPnPAlbumServices* self = new(ELeave) CUPnPAlbumServices();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::CUPnPAlbumServices
+// Default constructor.
+// --------------------------------------------------------------------------
+//    
+CUPnPAlbumServices::CUPnPAlbumServices() : iStatus( KErrNone )
+    {
+    // None.
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::ConstructL
+// 2nd phase constructor
+// --------------------------------------------------------------------------
+//    
+void CUPnPAlbumServices::ConstructL()
+    {
+    __LOG( "CUPnPAlbumServices::ConstructL" );
+    iAlbumNames = new (ELeave) CDesCArrayFlat(5);
+    iAlbumIds = new (ELeave) CDesCArrayFlat(5);
+
+    iCollectionUtility = MMPXCollectionUtility::NewL(
+        (MMPXCollectionObserver*)this, KMcModePlaylist );
+
+    // Open album collection plugin. Callback to HandleCollectionMessage.
+    CMPXCollectionPath* path = CMPXCollectionPath::NewL();
+    CleanupStack::PushL( path );
+    path->AppendL( KAlbumsCollectionUid );
+    iCollectionUtility->Collection().OpenL( *path );
+ 	CleanupStack::PopAndDestroy( path ); 
+
+    // Wait until signalled to proceed
+    iWait = new (ELeave) CActiveSchedulerWait();    
+    iWait->Start();     
+
+    __LOG1( "CUPnPAlbumServices::ConstructL - End %d", iStatus );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::ListAlbumsL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAlbumServices::ListAlbumsL(
+    CDesCArray& aAlbumIds,
+    CDesCArray& aAlbumNames )
+    {
+    __LOG( "CUPnPAlbumServices::ListAlbumsL" );
+    
+    // Check if already listed
+    
+    if( iStatus != KErrNone)
+        {
+        __LOG1( "CUPnPAlbumServices::ListAlbumsL iStatus %d return", iStatus );
+        return;
+        }
+    
+    if( iAlbumNames->Count() > 0 && iAlbumIds->Count() > 0 )
+        {
+        __LOG( "CUPnPAlbumServices::ListAlbumsL: Already fetched." );
+        // Copy from member
+        TInt count = iAlbumNames->Count();
+        __LOG1( "Album count=%d", count );
+        for( TInt i = 0; i < count; i++ )
+            {
+            aAlbumNames.AppendL( iAlbumNames->MdcaPoint(i) );
+            aAlbumIds.AppendL( iAlbumIds->MdcaPoint(i) );
+            }
+        __LOG( "CUPnPAlbumServices::ListAlbumsL: Return." );
+        return;
+        }
+
+    CMPXCollectionPath* path = iCollectionUtility->Collection().PathL();
+    CleanupStack::PushL( path );
+    path->SelectAllL();
+
+    RArray<TMPXAttribute> attrs;
+    CleanupClosePushL( attrs );
+    attrs.Append( KMPXMediaGeneralId );
+    attrs.Append( KMPXMediaGeneralTitle );
+
+    // Get album list from collection. Callback to HandleCollectionMediaL
+    iCollectionUtility->Collection().MediaL( *path, attrs.Array() );
+    CleanupStack::PopAndDestroy( &attrs );
+    CleanupStack::PopAndDestroy( path );
+
+    // Wait until signalled to proceed
+    iWait->Start();
+
+    if( iStatus != KErrNone )
+        {
+        if( iStatus == KErrNotFound )
+            {
+            // No albums available.
+            __LOG( "ListAlbumsL: No albums available!" );
+            return;
+            }
+        else // Some other problem
+            {
+            User::Leave( iStatus );
+            }
+        }
+
+    if ( iMedia != 0 )
+        {
+        TMPXAttribute mediaArrayAttr( KMPXMediaIdContainer,
+            EMPXMediaArrayContents );
+                
+        if( iMedia->IsSupported( mediaArrayAttr ) )
+            {
+            __LOG("getting album array");
+            CMPXMediaArray* medias = iMedia->ValueCObjectL<CMPXMediaArray>(
+                mediaArrayAttr );
+
+            if( medias )
+                {
+                CleanupStack::PushL( medias );
+                // Album count
+                TInt count = medias->Count();        
+                __LOG1( "Album count=%d", count );
+
+                for( TInt i = 0; i < count; ++i )
+                    {
+                    const CMPXMedia* entry = (*medias)[i];
+                    const TDesC& title = entry->ValueText(
+                        KMPXMediaGeneralTitle );
+                    __LOG3( "Title: %d/%d [%S]",i, count, &title );
+                    TMPXItemId id = *entry->Value<TMPXItemId>(
+                        KMPXMediaGeneralId );
+                    aAlbumNames.AppendL( title );
+                    iAlbumNames->AppendL( title ); // for later usage
+                    aAlbumIds.AppendL( Id2Desc( id ) );
+                    iAlbumIds->AppendL( Id2Desc( id ) ); // for later usage
+                    }
+                CleanupStack::PopAndDestroy( medias );
+                }
+            }
+        else
+            {
+            __LOG( "getting single item" );
+            const TDesC& title = iMedia->ValueText(
+                KMPXMediaGeneralTitle );
+            __LOG1( "Title: %S", &title );
+            TMPXItemId id = *iMedia->Value<TMPXItemId>(
+                KMPXMediaGeneralId );
+            aAlbumNames.AppendL( title );
+            iAlbumNames->AppendL( title ); // for later usage
+            aAlbumIds.AppendL( Id2Desc( id ) );
+            iAlbumIds->AppendL( Id2Desc( id ) ); // for later usage
+            }
+        delete iMedia;
+        iMedia = 0;
+        }
+
+    __LOG( "CUPnPAlbumServices::ListAlbumsL -End" );
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::OpenAlbumL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPAlbumServices::OpenAlbumL(
+    const TDesC& aAlbumId,
+    CDesCArray& aContentMedia )
+
+    {
+    
+
+    __LOG1( "CUPnPAlbumServices::OpenAlbumL(%S)", &aAlbumId );
+    
+  
+    if( iStatus != KErrNone)
+        {
+        __LOG1( "CUPnPAlbumServices::OpenAlbumL iStatus %d return", iStatus );
+        return;
+        }
+        
+    CMPXCollectionPath* path = iCollectionUtility->Collection().PathL();
+    CleanupStack::PushL( path );   
+    path->AppendL( Desc2Id( aAlbumId ) );
+
+    iCollectionUtility->Collection().OpenL( *path );
+ 	CleanupStack::PopAndDestroy( path );
+
+ 	// Wait until signalled to proceed
+    iWait->Start();
+
+ 	if( iStatus != KErrNone )
+        {
+        // Open album failed.
+        User::Leave( iStatus );
+        }
+
+    CMPXCollectionPath* mediaPath = iCollectionUtility->Collection().PathL();
+    CleanupStack::PushL( mediaPath );
+    mediaPath->SelectAllL();
+    
+    RArray<TMPXAttribute> attrs;
+    CleanupClosePushL( attrs );
+    attrs.Append( KMPXMediaGeneralUri );
+
+    // Get metadata of given album. Callback to HandleCollectionMediaL
+    iCollectionUtility->Collection().MediaL( *mediaPath, attrs.Array() );
+    CleanupStack::PopAndDestroy( &attrs );
+    CleanupStack::PopAndDestroy( mediaPath );
+
+    // Wait until signalled to proceed
+    iWait->Start();
+
+    if( iStatus != KErrNone )
+        {
+        if( iStatus == KErrNotFound )
+            {
+            // Album is empty
+            __LOG( "ListAlbumsL: Album is empty" );
+            return;
+            }
+        else // Some other problem
+            {
+            User::Leave( iStatus );
+            }
+        }
+
+    if ( iMedia != 0 )
+        {
+        __LOG( "CUPnPAlbumServices::iMedia exist! ");
+        TMPXAttribute mediaArrayAttr( KMPXMediaIdContainer,
+            EMPXMediaArrayContents );
+
+        // Check if there is more than one item in album
+        if( iMedia->IsSupported( mediaArrayAttr ) )
+            {
+            __LOG("getting album array");
+            CMPXMediaArray* medias = iMedia->ValueCObjectL<CMPXMediaArray>(
+                mediaArrayAttr );
+
+            if( medias )
+                {
+                __LOG( "CUPnPAlbumServices::album array exist! ");
+                CleanupStack::PushL( medias );
+                // Album count
+                TInt count = medias->Count();        
+                __LOG1( "Album count=%d", count );
+
+                for( TInt i = 0; i < count; ++i )
+                    {
+                    __LOG2( "accessing album: item %d of %d",i, count );
+                    const CMPXMedia* entry = (*medias)[i];
+                    const TDesC& uri = entry->ValueText(
+                        KMPXMediaGeneralUri );
+                    __LOG1( "Item uri:[%S]", &uri );
+                    aContentMedia.AppendL( entry->ValueText(
+                        KMPXMediaGeneralUri ) );
+                    }
+                 CleanupStack::PopAndDestroy( medias );
+                 }
+            }
+         else // Handle single item
+            {
+            __LOG("getting single item");
+            const TDesC& uri = iMedia->ValueText( KMPXMediaGeneralUri );
+            __LOG1( "Item uri:[%S]", &uri );
+            aContentMedia.AppendL( iMedia->ValueText( KMPXMediaGeneralUri ) );
+            }
+            
+        delete iMedia;
+        iMedia = 0;
+        }
+    __LOG( "CUPnPAlbumServices::OpenAlbumL - End ");
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::IsValidAlbumL
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CUPnPAlbumServices::IsValidAlbumL(
+    const TDesC& aAlbumName )
+    {
+    TBool found = EFalse;
+
+    __LOG1( "IsValidAlbumL(%S)", &aAlbumName );
+    
+    if( iStatus != KErrNone)
+        {
+        __LOG1( "CUPnPAlbumServices::IsValidAlbumL iStatus %d return", iStatus );
+        return EFalse;
+        }
+        
+    // Check if already listed
+    if( iAlbumNames->Count() > 0 )
+        {
+        __LOG( "CUPnPAlbumServices::IsValidAlbumL: Already fetched." );
+        TInt count = iAlbumNames->Count();
+        __LOG1( "Album count=%d", count );
+        for( TInt i = 0; i < count; i++ )
+            {
+            if( aAlbumName.Compare( iAlbumNames->MdcaPoint(i) ) == 0 )
+                {
+                __LOG( "IsValidAlbum -> True ");
+                i = count;
+                found = ETrue;
+                }
+            }
+        __LOG( "CUPnPAlbumServices::IsValidAlbumL: Return." );
+        return found;
+        }
+
+    // List albums
+    CMPXCollectionPath* mediaPath = iCollectionUtility->Collection().PathL();
+    CleanupStack::PushL( mediaPath );
+    mediaPath->SelectAllL();
+
+    RArray<TMPXAttribute> attrs;
+    CleanupClosePushL( attrs );
+    attrs.Append( KMPXMediaGeneralId );
+    attrs.Append( KMPXMediaGeneralTitle );
+
+    // Get album data. Callback to HandleCollectionMediaL
+    iCollectionUtility->Collection().MediaL( *mediaPath, attrs.Array() );
+    CleanupStack::PopAndDestroy( &attrs );
+    CleanupStack::PopAndDestroy( mediaPath );
+
+    // Wait until signalled to proceed
+    iWait->Start();
+
+    if( iStatus != KErrNone )
+        {
+        if( iStatus == KErrNotFound )
+            {
+            // No albums available
+            __LOG( "ListAlbumsL: No albums available" );
+            return EFalse;
+            }
+        else // Some other problem
+            {
+            User::Leave( iStatus );
+            }
+        }
+
+    if ( iMedia != 0 )
+        {
+        __LOG( "CUPnPAlbumServices::iMedia exist! ");
+        TMPXAttribute mediaArrayAttr( KMPXMediaIdContainer,
+            EMPXMediaArrayContents );
+                
+        if( iMedia->IsSupported( mediaArrayAttr ) )
+            {
+            __LOG("getting album array");
+            CMPXMediaArray* medias = iMedia->ValueCObjectL<CMPXMediaArray>(
+                mediaArrayAttr );
+
+            if( medias )
+                {
+                __LOG( "CUPnPAlbumServices::album array exist! ");
+                CleanupStack::PushL( medias );
+                // Album count
+                TInt count = medias->Count();        
+                __LOG1( "Album count=%d", count );
+
+                for( TInt i = 0; i < count; ++i )
+                    {
+                    const CMPXMedia* entry = (*medias)[i];
+                    if( aAlbumName.Compare( 
+                        entry->ValueText( KMPXMediaGeneralTitle ) ) == 0 )
+                        {
+                        __LOG( "IsValidAlbum -> True ");
+                        found = ETrue;
+                        break;
+                        }
+                    }
+                CleanupStack::PopAndDestroy( medias );
+                }
+            }
+        else
+            {
+            __LOG( "iMedia->IsSupported = False!" );
+            }
+        delete iMedia;
+        iMedia = 0;
+        }
+
+    __LOG( "CUPnPAlbumServices::IsValidAlbumL - End ");
+    return found;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::~CUPnPAlbumServices
+// Destructor.
+// --------------------------------------------------------------------------
+//
+EXPORT_C CUPnPAlbumServices::~CUPnPAlbumServices()
+    {
+    __LOG( "CUPnPAlbumServices::~CUPnPAlbumServices" );
+    iAlbumNames->Reset();
+    delete iAlbumNames;
+    iAlbumNames = 0;
+    iAlbumIds->Reset();
+    delete iAlbumIds;
+    iAlbumIds = 0;
+    
+    if ( iCollectionUtility )
+        {
+        iCollectionUtility->Close();
+        iCollectionUtility = 0;
+        }
+
+    delete iWait;
+    iWait = 0;
+
+    if( iMedia )
+        {
+        delete iMedia;
+        iMedia = 0;
+        }
+    }
+
+
+// Methods from MMPXCollectionObserver:
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::HandleCollectionMessage
+// Callback for Collection->OpenL()
+// --------------------------------------------------------------------------
+// 
+void CUPnPAlbumServices::HandleCollectionMessage( CMPXMessage* aMsg,
+    TInt aErr )
+
+    {
+    __LOG1( "HandleCollectionMessage: err=%d", aErr );
+	if( aErr == KErrNone)
+	    {
+	    TRAPD( error, DoHandleCollectionMessageL( aMsg ) );
+        if ( error != KErrNone )
+            {
+            __LOG1( "DoHandleCollectionMessageL: leave with %d", error );
+            iStatus = error;
+            iWait->AsyncStop();
+            }
+	    }
+	 else
+	    {
+	    iStatus = aErr;
+	    iWait->AsyncStop();
+	    }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::HandleCollectionMediaL
+// --------------------------------------------------------------------------
+//
+
+void CUPnPAlbumServices::HandleCollectionMediaL( const CMPXMedia& aMedia,
+    TInt aError )
+
+    {
+    __LOG1( "CUPnPAlbumServices::HandleCollectionMediaL: err=%d", aError );
+    if( aError == KErrNone )
+        {                    
+        // delete if already exist
+        if( iMedia )
+            {
+            delete iMedia;
+            iMedia = 0;
+            }
+        iMedia = CMPXMedia::NewL( aMedia );
+        }
+
+    iStatus = aError;
+    iWait->AsyncStop();
+
+    __LOG("CUPnPAlbumServices::HandleCollectionMediaL - End");
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::HandleOpenL
+// Callback for Collection->OpenL(path, attrs)
+// --------------------------------------------------------------------------
+// 
+void CUPnPAlbumServices::HandleOpenL( const CMPXMedia& /*aEntries*/,
+    TInt /*aIndex*/, TBool /*aComplete*/, TInt aError )
+    {
+    __LOG1( "CUPnPAlbumServices::HandleOpenL %d", aError);
+    
+    if( aError != KErrNone)
+        {
+        iStatus = aError;
+        iWait->AsyncStop();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::HandleOpenL
+// --------------------------------------------------------------------------
+// 
+void CUPnPAlbumServices::HandleOpenL( 
+    const CMPXCollectionPlaylist& /*aPlaylist*/, TInt aError )
+    {
+    __LOG1( "CUPnPAlbumServices::HandleOpenL %d", aError);
+    
+    if( aError != KErrNone)
+        {
+        iStatus = aError;
+        iWait->AsyncStop();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// Converts an ID from TMPXItemId form to descriptor form.
+// --------------------------------------------------------------------------
+//
+const TDesC& CUPnPAlbumServices::Id2Desc( const TMPXItemId& aId )
+    {  
+    iTempBuffer.Num( aId );
+    return iTempBuffer;
+    }
+
+// --------------------------------------------------------------------------
+// Converts an ID from descriptor form to TMPXItemId form.
+// --------------------------------------------------------------------------
+//
+TMPXItemId CUPnPAlbumServices::Desc2Id( const TDesC& aDesc )
+    {
+    TLex convert( aDesc );
+    TUint temp;
+    convert.Val( temp, EDecimal );
+    TMPXItemId id(temp);
+    return id;
+    }
+
+// --------------------------------------------------------------------------
+// CUPnPAlbumServices::DoHandleCollectionMessageL
+// --------------------------------------------------------------------------
+//
+void CUPnPAlbumServices::DoHandleCollectionMessageL( CMPXMessage* aMsg )
+    {
+    __LOG( "CUPnPAlbumServices::DoHandleCollectionMessageL" );
+
+    if( aMsg && aMsg->IsSupported(KMPXMessageGeneralEvent ) &&
+			aMsg->IsSupported(KMPXMessageGeneralType ) )
+        {
+	    TInt event( *aMsg->Value<TInt>( KMPXMessageGeneralEvent ) );
+	    TInt type( *aMsg->Value<TInt>( KMPXMessageGeneralType ) );
+	    TInt data( *aMsg->Value<TInt>( KMPXMessageGeneralData ) );
+	    
+	    __LOG1("Event: %d", event );
+	    __LOG1("Type: %d", type );
+	    __LOG1("Data: %d", data );
+	     	        
+	    switch ( event )
+            {
+            case TMPXCollectionMessage::EPathChanged:
+                {
+                __LOG( "TMPXCollectionMessage::EPathChanged" );
+                if( type == EMcPathChangedByOpen )
+                    {
+                    __LOG( " Type: EMcPathChangedByOpen " );
+                    // Album collection is ready for use
+                    iStatus = KErrNone;
+                    iWait->AsyncStop();
+                    }
+                }    
+            break;
+            default:
+                {
+                // do nothing
+                } 
+                break;
+            }
+	   }
+    }
+
+