upnpframework/upnpmusicadapter/src/upnpalbumservices.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:52:00 +0200
changeset 0 7f85d04be362
child 30 5ec426854821
permissions -rw-r--r--
Revision: 200947 Kit: 200951

/*
* 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;
            }
	   }
    }