--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpframework/upnpmusicadapter/src/upnpplaylistservices.cpp Thu Dec 17 08:52:00 2009 +0200
@@ -0,0 +1,832 @@
+/*
+* Copyright (c) 2006 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 playlist handling services for UPnP framework
+*
+*/
+
+
+// INCLUDES
+// System
+#include <escapeutils.h> // for unicode conversion
+
+// upnp stack api
+#include <upnpitem.h> // s60 upnp stack
+#include <upnpelement.h> // s60 upnp stack
+
+// MPX framework api
+#include <mpxcollectionutility.h>
+#include <mpxcollectionframeworkdefs.h> // main attribute keys
+#include <mpxmediageneraldefs.h> // commonly used attribute keys
+#include <mpxmediacontainerdefs.h> // container-specific attribute keys
+#include <mpxmediamusicdefs.h> // music-specific attribute keys
+#include <mpxcollectionplugin.hrh> // collection plugin types
+#include <mpxmedia.h>
+#include <mpxmediaarray.h>
+
+// upnpframework / avcontroller helper api
+#include "upnpitemutility.h" // for FindElementByName & ResourceFromItemL
+#include "upnpconstantdefs.h" // for element names
+
+// upnpframework / internal api's
+#include "upnpcdsreselementutility.h" // for UriFromItemL
+
+// music adapter internal
+#include "upnpmpxhelper.h" // for some mpx operations
+#include "upnpplaylistservices.h" // ourselves
+
+// upnpframework / settings engine api
+#include "upnpsettingsengine.h" // CUPnPSettingsEngine
+
+// debug
+_LIT16( KComponentLogfile, "musicadapter.txt" );
+#include "upnplog.h"
+
+
+// constant definitions
+const TUid KHomeConnectUid = { 0x10208A0A };
+const TUid KMpxLocalCollectionUid = { 0x101FFC3A };
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::NewL
+// 1st phase constructor.
+// --------------------------------------------------------------------------
+//
+EXPORT_C CUPnPPlaylistServices* CUPnPPlaylistServices::NewL()
+ {
+ __LOG( "CUPnPPlaylistServices::NewL" );
+
+ CUPnPPlaylistServices* self = new(ELeave) CUPnPPlaylistServices();
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::CUPnPPlaylistServices
+// Default constructor.
+// --------------------------------------------------------------------------
+//
+CUPnPPlaylistServices::CUPnPPlaylistServices()
+ {
+ }
+
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::CUPnPPlaylistServices
+// 2nd phase constructor
+// --------------------------------------------------------------------------
+//
+void CUPnPPlaylistServices::ConstructL()
+ {
+ __LOG( "CUPnPPlaylistServices::ConstructL" );
+ iStatus = KErrNone;
+
+ iCollectionUtility = MMPXCollectionUtility::NewL(
+ (MMPXCollectionObserver*)0, KMcModePlaylist );
+
+ // Initialize/Merge music collection databases
+ RArray<TUid> uid;
+ CleanupClosePushL( uid );
+ uid.AppendL( TUid::Uid( EMPXCollectionPluginMusic ) );
+ TUid collection = iCollectionUtility->CollectionIDL( uid.Array() );
+ TRAP( iStatus, iCollectionUtility->Collection().CommandL(
+ EMcCmdCollectionInit, collection.iUid ) );
+ CleanupStack::PopAndDestroy( &uid );
+
+ iMpxHelper = CUPnPMpxHelper::NewL( KHomeConnectUid );
+
+
+ __LOG1( "CUPnPPlaylistServices::ConstructL end iStatus %d",
+ iStatus );
+ }
+
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::~CUPnPPlaylistServices
+// Destructor.
+// --------------------------------------------------------------------------
+//
+EXPORT_C CUPnPPlaylistServices::~CUPnPPlaylistServices()
+ {
+ __LOG( "CUPnPPlaylistServices ~()" );
+ if ( iCollectionUtility )
+ {
+ iCollectionUtility->Close();
+ iCollectionUtility = 0;
+ }
+
+ delete iMpxHelper;
+ }
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::ListPlaylistsL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPPlaylistServices::ListPlaylistsL(
+ CDesCArray& aPlaylistIds,
+ CDesCArray& aPlaylistNames )
+ {
+ __LOG( "ListPlaylistsL()" );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::ListPlaylistsL iStatus %d return",
+ iStatus );
+ return;
+ }
+
+ CMPXMedia* result = FindItemL( EPlaylists,
+ KNullDesC, &KMPXMediaGeneralId, &KMPXMediaGeneralTitle );
+ if ( result != 0 )
+ {
+ CleanupStack::PushL( result );
+ __LOG("getting media array");
+ const CMPXMediaArray* medias = result->Value<CMPXMediaArray>(
+ KMPXMediaArrayContents );
+ TInt count = medias->Count();
+ for( TInt i = 0; i < count; ++i )
+ {
+ const CMPXMedia* entry = (*medias)[i];
+ TMPXItemId id = *entry->Value<TMPXItemId>(
+ KMPXMediaGeneralId );
+ const TDesC& title = entry->ValueText(
+ KMPXMediaGeneralTitle );
+ __LOG3( "media array %d/%d [%S]",
+ i, count, &title );
+ aPlaylistIds.AppendL( Id2Desc( id ) );
+ aPlaylistNames.AppendL( title );
+ }
+ CleanupStack::PopAndDestroy( result );
+ }
+ }
+
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::OpenPlaylistL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPPlaylistServices::OpenPlaylistL(
+ const TDesC& aPlaylistId,
+ CDesCArray& aContentMedia )
+ {
+ __LOG1( "OpenPlaylistL(%S)", &aPlaylistId );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::OpenPlaylistL iStatus %d return",
+ iStatus );
+ return;
+ }
+
+ CMPXMedia* result = FindItemL( EPlaylistById, aPlaylistId,
+ &KMPXMediaArrayContents, &KMPXMediaGeneralUri );
+ if ( result != 0 )
+ {
+ CleanupStack::PushL( result );
+ const CMPXMediaArray* resultMedias =
+ result->Value<CMPXMediaArray>( KMPXMediaArrayContents );
+
+ if ( resultMedias->Count() == 1 )
+ {
+ // fetch content
+ CMPXMedia* playlist = FetchPlaylistContentL( aPlaylistId );
+ if( playlist != 0 )
+ {
+ CleanupStack::PushL( playlist );
+ const CMPXMediaArray* playlistMedias =
+ playlist->Value<CMPXMediaArray>( KMPXMediaArrayContents );
+ if ( playlistMedias )
+ {
+ TInt count = playlistMedias->Count();
+ for( TInt i = 0; i < count; ++i )
+ {
+ __LOG2( "accessing mediaList: item %d of %d",
+ i, count );
+ const CMPXMedia* entry = (*playlistMedias)[i];
+ aContentMedia.AppendL( entry->ValueText(
+ KMPXMediaGeneralUri ) );
+ }
+ }
+ CleanupStack::PopAndDestroy( playlist );
+ }
+ }
+ else
+ {
+ __LOG1("Unknown result medias count: %d",
+ resultMedias->Count() );
+ }
+ CleanupStack::PopAndDestroy( result );
+ }
+ else
+ {
+ User::Leave( KErrNotFound );
+ }
+ // now ready to return
+ }
+
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::CreateTrackL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPPlaylistServices::CreateTrackL(
+ const TDesC& aTrackPath,
+ const CUpnpItem& aTrackMetadata )
+ {
+ __LOG1( "CreateTrackL(%S)", &aTrackPath );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::CreateTrackL iStatus %d return",
+ iStatus );
+ return;
+ }
+
+ CMPXMedia* item = CMPXMedia::NewL();
+ CleanupStack::PushL( item );
+ item->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ item->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+ item->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXSong );
+ item->SetTextValueL(
+ KMPXMediaGeneralUri, aTrackPath );
+ // Insert metadata
+ HBufC16* buf = NULL;
+ // title
+ buf = EscapeUtils::ConvertToUnicodeFromUtf8L( aTrackMetadata.Title() );
+ CleanupStack::PushL( buf );
+ item->SetTextValueL(
+ KMPXMediaGeneralTitle, *buf );
+ CleanupStack::PopAndDestroy( buf );
+ // artist
+ if ( ( buf = GetElementLC( aTrackMetadata, KElementArtist ) ) != 0 )
+ {
+ item->SetTextValueL(
+ KMPXMediaMusicArtist, *buf );
+ CleanupStack::PopAndDestroy( buf );
+ }
+ else if ( ( buf = GetElementLC( aTrackMetadata, KElementCreator ) ) != 0 )
+ {
+ item->SetTextValueL(
+ KMPXMediaMusicArtist, *buf );
+ CleanupStack::PopAndDestroy( buf );
+ }
+ // album
+ if ( ( buf = GetElementLC( aTrackMetadata, KElementAlbum ) ) != 0 )
+ {
+ item->SetTextValueL(
+ KMPXMediaMusicAlbum, *buf );
+ CleanupStack::PopAndDestroy( buf );
+ }
+ // genre
+ if ( ( buf = GetElementLC( aTrackMetadata, KElementGenre ) ) != 0 )
+ {
+ item->SetTextValueL(
+ KMPXMediaMusicGenre, *buf );
+ CleanupStack::PopAndDestroy( buf );
+ }
+ // date and year
+ const CUpnpElement* elem = UPnPItemUtility::FindElementByName(
+ aTrackMetadata, KElementDate );
+ if ( elem != 0 )
+ {
+ TTime timestamp;
+ TInt err =
+ UPnPItemUtility::UPnPDateAsTTime( elem->Value(), timestamp );
+ if( err == KErrNone )
+ {
+ item->SetTObjectValueL<TInt64>(
+ KMPXMediaGeneralDate, timestamp.Int64() );
+
+ item->SetTObjectValueL<TInt64>(
+ KMPXMediaMusicYear, timestamp.Int64() );
+ }
+ }
+
+ // duration
+ const CUpnpElement* trackResource =
+ &UPnPItemUtility::ResourceFromItemL( aTrackMetadata );
+
+ if( trackResource != 0 )
+ {
+ const CUpnpAttribute* attr = UPnPItemUtility
+ ::FindAttributeByName( *trackResource, KAttributeDuration );
+
+ if ( attr != 0 )
+ {
+ TInt ms = 0;
+ UPnPItemUtility
+ ::UPnPDurationAsMilliseconds( attr->Value(), ms );
+
+ item->SetTObjectValueL<TInt>(
+ KMPXMediaGeneralDuration, ms );
+ }
+ }
+
+ // track number
+ if ( ( buf = GetElementLC( aTrackMetadata, KElementTrackNumber ) ) != 0 )
+ {
+ item->SetTextValueL(
+ KMPXMediaMusicAlbumTrack, *buf );
+ CleanupStack::PopAndDestroy( buf );
+ }
+
+ __LOG("...about to add track...");
+ iMpxHelper->AddTrackL( item );
+
+ CleanupStack::PopAndDestroy( item );
+ }
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::GetElement
+// --------------------------------------------------------------------------
+//
+HBufC16* CUPnPPlaylistServices::GetElementLC(
+ const CUpnpItem& aSource, const TDesC8& aSourceField ) const
+ {
+ HBufC16* result = 0;
+ const CUpnpElement* elem = UPnPItemUtility::FindElementByName(
+ aSource, aSourceField );
+ if ( elem != 0 )
+ {
+ result = EscapeUtils::ConvertToUnicodeFromUtf8L( elem->Value() );
+ CleanupStack::PushL( result );
+ }
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::CreatePlaylistL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPPlaylistServices::CreatePlaylistL(
+ const TDesC& aPlaylistName,
+ const MDesCArray& aTrackPaths,
+ TDes* aPlaylistId )
+ {
+ __LOG1( "CreatePlaylistL(%S)", &aPlaylistName );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::CreatePlaylistL iStatus %d return",
+ iStatus );
+ return;
+ }
+
+ // create a media list
+ CMPXMediaArray* medias = CMPXMediaArray::NewL();
+ CleanupStack::PushL( medias );
+
+ // add track info into the media list
+ for( TInt i = 0; i < aTrackPaths.MdcaCount(); ++i )
+ {
+ TPtrC16 trackUri = aTrackPaths.MdcaPoint(i);
+ CMPXMedia* entry = CMPXMedia::NewL();
+ CleanupStack::PushL( entry );
+ entry->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ entry->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+ entry->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXSong );
+ entry->SetTextValueL(
+ KMPXMediaGeneralUri, trackUri );
+ medias->AppendL( entry );
+ CleanupStack::Pop( entry );
+ }
+
+ // create a media item for the playlist
+ CMPXMedia* playlist = CMPXMedia::NewL();
+ CleanupStack::PushL( playlist );
+
+ CUPnPSettingsEngine* engine = CUPnPSettingsEngine::NewL();;
+ CleanupStack::PushL( engine );
+
+ HBufC* location = HBufC::NewLC( KMaxFileName );
+ TPtr locationPtr( location->Des() );
+ TBool isPhoneMemory;
+ engine->GetCopyLocationL( locationPtr, isPhoneMemory );
+
+ // add playlist info into the playlist media
+ playlist->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ playlist->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+ playlist->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXPlaylist );
+ playlist->SetTextValueL(
+ KMPXMediaGeneralTitle, aPlaylistName );
+ playlist->SetTextValueL(
+ KMPXMediaGeneralUri, locationPtr );
+ playlist->SetCObjectValueL(
+ KMPXMediaArrayContents, medias );
+ playlist->SetTObjectValueL<TInt>(
+ KMPXMediaArrayCount, medias->Count() );
+
+ // add in collection
+ __LOG("...about to add playlist...");
+ iMpxHelper->AddPlaylistL( playlist );
+
+ iCurrentId = *playlist->Value<TMPXItemId>(
+ KMPXMediaGeneralId );
+
+ CleanupStack::PopAndDestroy( location );
+ CleanupStack::PopAndDestroy( engine );
+ CleanupStack::PopAndDestroy( playlist );
+ CleanupStack::PopAndDestroy( medias );
+
+ // Find out playlist ID
+ if ( aPlaylistId )
+ {
+ __LOG("...about to retrieve playlist id...");
+ aPlaylistId->Copy( Id2Desc( iCurrentId ) );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::AddMediaToPlaylistL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPPlaylistServices::AddMediaToPlaylistL(
+ const TDesC& aPlaylistId,
+ const TDesC& aTrackPath )
+ {
+ __LOG2( "AddMediaToPlaylistL(%S,%S)",
+ &aPlaylistId, &aTrackPath );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::AddMediaToPlaylistL iStatus %d return",
+ iStatus );
+ return;
+ }
+
+ // create a media list
+ CMPXMediaArray* medias = CMPXMediaArray::NewL();
+ CleanupStack::PushL( medias );
+
+ // add new track to media list
+ CMPXMedia* entry = CMPXMedia::NewL();
+ CleanupStack::PushL( entry );
+ entry->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ entry->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+ entry->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXSong );
+ entry->SetTextValueL(
+ KMPXMediaGeneralUri, aTrackPath );
+ medias->AppendL( entry );
+ CleanupStack::Pop( entry );
+
+ // create the playlist delta
+ CMPXMedia* playlistDelta = CMPXMedia::NewL();
+ CleanupStack::PushL( playlistDelta );
+
+ // add playlist info into the playlist delta media
+ playlistDelta->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ playlistDelta->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+ playlistDelta->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXPlaylist );
+ playlistDelta->SetTObjectValueL<TMPXItemId>(
+ KMPXMediaGeneralId, Desc2Id( aPlaylistId ) );
+ playlistDelta->SetCObjectValueL(
+ KMPXMediaArrayContents, medias ); // new content
+ playlistDelta->SetTObjectValueL<TInt>(
+ KMPXMediaArrayCount, medias->Count() );
+
+ // add in collection
+ __LOG("Add playlist delta to collection");
+ iMpxHelper->AddPlaylistL( playlistDelta );
+
+ CleanupStack::PopAndDestroy( playlistDelta );
+ CleanupStack::PopAndDestroy( medias );
+ }
+
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::DeleteTrackL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPPlaylistServices::DeleteTrackL(
+ const TDesC& aContentFile )
+ {
+ __LOG1( "DeleteTrackL(%S)", &aContentFile );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::DeleteTrackL iStatus %d return",
+ iStatus );
+ return;
+ }
+
+ // item to delete
+ CMPXMedia* item = CMPXMedia::NewL();
+ CleanupStack::PushL( item );
+ item->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ item->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+ item->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXSong );
+ item->SetTextValueL(
+ KMPXMediaGeneralUri, aContentFile );
+ iCollectionUtility->Collection().RemoveL( *item );
+ CleanupStack::PopAndDestroy( item );
+ }
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::DeletePlaylistL
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUPnPPlaylistServices::DeletePlaylistL(
+ const TDesC& aPlaylistId )
+ {
+ __LOG1( "DeletePlaylistL(%S)", &aPlaylistId );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::DeletePlaylistL iStatus %d return",
+ iStatus );
+ return;
+ }
+
+ // item to delete
+ CMPXMedia* playlist = CMPXMedia::NewL();
+ CleanupStack::PushL( playlist );
+ playlist->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ playlist->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+ playlist->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXPlaylist );
+ playlist->SetTObjectValueL<TMPXItemId>(
+ KMPXMediaGeneralId, Desc2Id( aPlaylistId ) );
+ iCollectionUtility->Collection().RemoveL( *playlist );
+ CleanupStack::PopAndDestroy( playlist );
+ }
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::IsValidTrackL
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CUPnPPlaylistServices::IsValidTrackL(
+ const TDesC& aContentFile )
+ {
+ __LOG1( "IsValidTrackL(%S)", &aContentFile );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::IsValidTrackL iStatus %d return",
+ iStatus );
+ return EFalse;
+ }
+
+ TBool found = EFalse;
+ CMPXMedia* track = FindItemL( ESongByUri, aContentFile );
+ if ( track != 0 )
+ {
+ CleanupStack::PushL( track );
+ TInt count = *track->Value<TInt>( KMPXMediaArrayCount );
+ if ( count >= 0 )
+ {
+ found = ETrue;
+ }
+ CleanupStack::PopAndDestroy( track );
+ }
+
+ return found;
+ }
+
+// --------------------------------------------------------------------------
+// CUPnPPlaylistServices::IsValidPlaylistL
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CUPnPPlaylistServices::IsValidPlaylistL(
+ const TDesC& aPlaylistTitle )
+ {
+ __LOG1( "IsValidPlaylistL(%S)", &aPlaylistTitle );
+
+ if( iStatus != KErrNone)
+ {
+ __LOG1( "CUPnPPlaylistServices::IsValidPlaylistL iStatus %d return",
+ iStatus );
+ return EFalse;
+ }
+
+ TBool found = EFalse;
+ // find the playlist
+ CMPXMedia* playlist = FindItemL( EPlaylistByTitle, aPlaylistTitle );
+ if ( playlist != 0 )
+ {
+ CleanupStack::PushL( playlist );
+ TInt count = *playlist->Value<TInt>( KMPXMediaArrayCount );
+ if ( count >= 0 )
+ {
+ found = ETrue;
+ }
+ CleanupStack::PopAndDestroy( playlist );
+ }
+
+ return found;
+ }
+
+
+// --------------------------------------------------------------------------
+// Find a playlist
+// --------------------------------------------------------------------------
+//
+CMPXMedia* CUPnPPlaylistServices::FindItemL(
+ TFindCategory aCategory,
+ const TDesC& aKey,
+ const TMPXAttributeData* aAttribute1,
+ const TMPXAttributeData* aAttribute2,
+ const TMPXAttributeData* aAttribute3 )
+ {
+ __LOG( "FindItemL" );
+ CMPXMedia* criteria = CMPXMedia::NewL();
+ CleanupStack::PushL( criteria );
+ criteria->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ criteria->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXItem );
+
+ // set search keys
+ if ( aCategory == ESongs ||
+ aCategory == ESongByUri )
+ {
+ criteria->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXSong );
+ if ( aCategory == ESongByUri )
+ {
+ criteria->SetTextValueL(
+ KMPXMediaGeneralUri, aKey );
+ }
+ }
+ else if ( aCategory == EPlaylists ||
+ aCategory == EPlaylistById ||
+ aCategory == EPlaylistByTitle )
+ {
+ criteria->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXPlaylist );
+ if ( aCategory == EPlaylistById )
+ {
+ criteria->SetTObjectValueL<TMPXItemId>(
+ KMPXMediaGeneralId, Desc2Id( aKey ) );
+ }
+ else if ( aCategory == EPlaylistByTitle )
+ {
+ criteria->SetTextValueL(
+ KMPXMediaGeneralTitle, aKey );
+ }
+ }
+ else
+ {
+ __PANICD( __FILE__, __LINE__ );
+ }
+
+
+ // define attributes fetched
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL( attributes );
+ if ( aAttribute1 )
+ {
+ // add attribute 1
+ attributes.AppendL( *aAttribute1 );
+ if ( aAttribute2 )
+ {
+ // add attribute 2
+ attributes.AppendL( *aAttribute2 );
+ if ( aAttribute3 )
+ {
+ // add attribute 3
+ attributes.AppendL( *aAttribute3 );
+ }
+ }
+ }
+ else
+ {
+ // add a dummy attribute because the query will fail if
+ // there are no attributes
+ attributes.AppendL( KMPXMediaGeneralId );
+ }
+
+ // now find
+ CMPXMedia* result = 0;
+ TRAPD( err, result = iCollectionUtility->Collection()
+ .FindAllL( *criteria , attributes.Array() ) );
+ CleanupStack::PopAndDestroy(); // attributes
+ CleanupStack::PopAndDestroy( criteria );
+
+ if ( err == KErrNotFound ||
+ err == KErrPathNotFound )
+ {
+ __LOG1( "FindAll: err=%d - not found.", err );
+ result = 0;
+ }
+ else if ( err != KErrNone )
+ {
+ __LOG1("FindAll: error=%d", err);
+ User::Leave( err );
+ }
+ else
+ {
+ __LOG( "FindAll: ok" );
+ }
+
+ return result;
+ }
+
+
+// --------------------------------------------------------------------------
+// Fetch a playlist content
+// --------------------------------------------------------------------------
+//
+CMPXMedia* CUPnPPlaylistServices::FetchPlaylistContentL( const TDesC& aId )
+ {
+ __LOG( "FindPlaylistContentL" );
+ CMPXMedia* criteria = CMPXMedia::NewL();
+ CleanupStack::PushL( criteria );
+ criteria->SetTObjectValueL<TUid>(
+ KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid );
+ criteria->SetTObjectValueL<TMPXGeneralType>(
+ KMPXMediaGeneralType, EMPXGroup );
+
+ // set search keys
+ criteria->SetTObjectValueL<TMPXGeneralCategory>(
+ KMPXMediaGeneralCategory, EMPXSong );
+ criteria->SetTObjectValueL<TMPXItemId>(
+ KMPXMediaGeneralId, Desc2Id( aId ) );
+
+ // define attributes fetched
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL( attributes );
+ attributes.AppendL( KMPXMediaGeneralUri );
+
+ // now find
+ CMPXMedia* result = 0;
+ TRAPD( err, result = iCollectionUtility->Collection()
+ .FindAllL( *criteria , attributes.Array() ) );
+ CleanupStack::PopAndDestroy(); // attributes
+ CleanupStack::PopAndDestroy( criteria );
+
+ if ( err == KErrNotFound ||
+ err == KErrPathNotFound )
+ {
+ __LOG1( "FindAll: err=%d - not found.", err );
+ result = 0;
+ }
+ else if ( err != KErrNone )
+ {
+ __LOG1("FindAll: error=%d", err);
+ User::Leave( err );
+ }
+ else
+ {
+ __LOG( "FindAll: ok" );
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// Converts an ID from TMPXItemId form to descriptor form.
+// --------------------------------------------------------------------------
+//
+const TDesC& CUPnPPlaylistServices::Id2Desc( const TMPXItemId& aId )
+ {
+ iTempBuffer.Num( aId );
+ return iTempBuffer;
+ }
+
+// --------------------------------------------------------------------------
+// Converts an ID from descriptor form to TMPXItemId form.
+// --------------------------------------------------------------------------
+//
+TMPXItemId CUPnPPlaylistServices::Desc2Id( const TDesC& aDesc )
+ {
+ TLex convert( aDesc );
+ TUint temp;
+ convert.Val( temp, EDecimal );
+ TMPXItemId id(temp);
+ return id;
+ }