diff -r 2bb96f4ecad8 -r 8e7494275d3a omads/omadsextensions/adapters/mediads/src/mediamanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omads/omadsextensions/adapters/mediads/src/mediamanager.cpp Tue Aug 31 15:05:37 2010 +0300 @@ -0,0 +1,1254 @@ +/* +* Copyright (c) 2009-2010 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: CMediaManager class implementation +* +*/ + + + +#include "mediamanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include // for EMPXPlaylistTypeM3U +#include +#include +#include +#include +#include +#include +#include + +#include "mediadsproviderdefs.h" +#include "playlistitem.h" +#include "logger.h" + + +const TUid KMpxLocalCollectionUid = { 0x101FFC3A }; + +_LIT( KPlaylistPath, "playlists\\" ); +_LIT( KMPXVirtualPlaylistExt, ".vir" ); + +// Maximum amount of song items to be enumerated on one RunL. +const TInt iMaxSongItemsToEnumerate(100); +// Maximum amount of playlist items to be enumerated on one RunL. +const TInt iMaxPlaylistItemsToEnumerate(15); + + +CMediaManager::CMediaManager( RFs& aFs, MMediaManagerObserver* aObserver, + TKeyArrayFix aKey, CMD5& aHasher ) +: CActive( EPriorityStandard ), +iObserver( aObserver ), +iKey( aKey ), +iHasher( aHasher ), +iFs( aFs ) + { + TRACE_FUNC; + CActiveScheduler::Add(this); + } + + +void CMediaManager::ConstructL() + { + TRACE_FUNC_ENTRY; + iHarvester = CMPXHarvesterFactory::NewL(); + LOGGER_WRITE("1"); + iCollection = MMPXCollectionUtility::NewL( iObserver ); + LOGGER_WRITE("2"); + iMediator = CMPXCollectionMediator::NewL( iCollection->Collection() ); + LOGGER_WRITE("3"); + iCollectionHelper = CMPXCollectionHelperFactory::NewCollectionCachedHelperL(); + + TRACE_FUNC_EXIT; + } + + +CMediaManager* CMediaManager::NewL( RFs& aFs, MMediaManagerObserver* aObserver, TKeyArrayFix aKey, CMD5& aHasher ) + { + CMediaManager* self = new( ELeave ) CMediaManager( aFs, aObserver, aKey, aHasher ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CMediaManager::~CMediaManager() + { + TRACE_FUNC_ENTRY; + Cancel(); + delete iFoundedMedia; + if ( iCollectionHelper ) + { + iCollectionHelper->Close(); + iCollectionHelper = NULL; + } + + delete iMediator; + + if ( iCollection ) + { + iCollection->Close(); + iCollection = NULL; + } + + if ( iHarvester ) + { + // For some unknown reason this may sometimes leave with error code -38 + TRAP_IGNORE( iHarvester->Close() ); + iHarvester = NULL; + } + + TRACE_FUNC_EXIT; + } + +void CMediaManager::ScanL() + { + TRACE_FUNC_ENTRY; + iHarvester->ScanL(); + TRACE_FUNC_EXIT; + } + +void CMediaManager::CancelScanL() + { + TRACE_FUNC_ENTRY; + iHarvester->CancelScanL(); + TRACE_FUNC_EXIT; + } + +// -------------------------------------------------------------------------- +// Starts registering all playlists. Calls RegisterAllPlayListsCompleted when ready +// -------------------------------------------------------------------------- +// +TInt CMediaManager::RegisterAllPlayLists() + { + TRACE_FUNC_ENTRY; + if ( iCurrentState != EIdle || !iSnapshotArray) + { + LOGGER_WRITE("Not Idle or iSnapshotArray is NULL"); + return KErrNotReady; + } + iCurrentState = EReadingPlaylistCount; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + TRACE_FUNC_EXIT; + return KErrNone; + } + +// -------------------------------------------------------------------------- +// Starts registering all song items. Calls RegisterAllSongsCompleted when ready +// -------------------------------------------------------------------------- +// +TInt CMediaManager::RegisterAllSongs() + { + TRACE_FUNC_ENTRY; + if ( iCurrentState != EIdle || !iSnapshotArray) + { + LOGGER_WRITE("Not Idle or iSnapshotArray is NULL"); + return KErrNotReady; + } + iCurrentState = EReadingSongCount; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + TRACE_FUNC_EXIT; + return KErrNone; + } + +// -------------------------------------------------------------------------- +// Registers playlist. +// -------------------------------------------------------------------------- +// +void CMediaManager::RegisterPlaylistL( const CMPXMedia& aMedia ) + { + TRACE_FUNC_ENTRY; + if ( !iSnapshotArray ) + { + User::Leave( KErrGeneral ); + } + + if ( !aMedia.IsSupported(KMPXMediaGeneralId) ) + { + LOGGER_WRITE("KMPXMediaGeneralId not supported"); + User::Leave(KErrNotSupported); + } + + // Extract the playlist id from the found object + TUint32 playlistId = *aMedia.Value(KMPXMediaGeneralId); + LOGGER_WRITE_1("KMPXMediaGeneralId: %d", playlistId); + + if ( !aMedia.IsSupported( KMPXMediaGeneralTitle ) ) + { + LOGGER_WRITE("KMPXMediaGeneralTitle not supported"); + User::Leave(KErrNotSupported); + } + + CPlaylistItem* playlist = CPlaylistItem::NewLC(); + // find the media object that contains a list of songs in the playlist + + RArray contentIDs; + CleanupClosePushL( contentIDs ); + contentIDs.AppendL(KMPXMediaIdGeneral); + + CMPXMedia* searchMedia = CMPXMedia::NewL(contentIDs.Array()); + CleanupStack::PopAndDestroy( &contentIDs ); + CleanupStack::PushL(searchMedia); + + searchMedia->SetTObjectValueL(KMPXMediaGeneralType, EMPXGroup); + searchMedia->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXSong); + searchMedia->SetTObjectValueL(KMPXMediaGeneralId, playlistId); + + RArray songAttributes; + CleanupClosePushL(songAttributes); + songAttributes.AppendL(KMPXMediaGeneralId); + songAttributes.AppendL(KMPXMediaGeneralUri); + + CMPXMedia* foundMedia = iCollectionHelper->FindAllL(*searchMedia, + songAttributes.Array()); + CleanupStack::PopAndDestroy(&songAttributes); + CleanupStack::PopAndDestroy(searchMedia); + + CleanupStack::PushL(foundMedia); + + + if ( !foundMedia->IsSupported(KMPXMediaArrayCount) ) + { + User::Leave(KErrNotSupported); + } + + // Number of references + TInt numOfRefs = *foundMedia->Value(KMPXMediaArrayCount); + if ( numOfRefs ) + { + if (!foundMedia->IsSupported(KMPXMediaArrayContents)) + { + User::Leave(KErrNotSupported); + } + + const CMPXMediaArray* refArray = + foundMedia->Value(KMPXMediaArrayContents); + + // Import the references + for (TInt i=0;iIsSupported(KMPXMediaGeneralUri) ) + { + const TDesC& uri = refMedia->ValueText(KMPXMediaGeneralUri); + playlist->AddItemL( uri ); + } + + } + } + + TSnapshotItem playlistItem(playlistId); + + const TDesC& title = aMedia.ValueText( KMPXMediaGeneralTitle ); + playlist->SetTitleL( title ); + + const TDesC& uri = aMedia.ValueText( KMPXMediaGeneralUri ); + playlist->SetUrlL( uri ); + + playlistItem.SetItemHash( *playlist, iHasher ); + + playlistItem.SetParentId( KPlaylistsFolderId ); + TKeyArrayFix key( iKey ); + iSnapshotArray->InsertIsqL( playlistItem, key ); + + CleanupStack::PopAndDestroy( foundMedia ); + CleanupStack::PopAndDestroy( playlist ); + + TRACE_FUNC_EXIT; + } + +// -------------------------------------------------------------------------- +// Populates CPlaylistItem +// -------------------------------------------------------------------------- +// +void CMediaManager::GetPlayListL( TInt aPlaylistId, CPlaylistItem& aList ) + { + TRACE_FUNC_ENTRY; + + LOGGER_WRITE_1("aPlaylistId: %d", aPlaylistId); + + CMPXMedia* playlistItem = FindPlaylistL( aPlaylistId ); + CleanupStack::PushL( playlistItem ); + if ( !playlistItem->IsSupported(KMPXMediaGeneralId) ) + { + LOGGER_WRITE("KMPXMediaGeneralId not supported"); + User::Leave(KErrNotSupported); + } + + // Extract the playlist id from the found object + TUint32 playlistId = *playlistItem->Value(KMPXMediaGeneralId); + LOGGER_WRITE_1("KMPXMediaGeneralId: %d", playlistId); + aList.SetId( playlistId ); + + if ( !playlistItem->IsSupported(KMPXMediaGeneralTitle) ) + { + LOGGER_WRITE("KMPXMediaGeneralTitle not supported"); + User::Leave( KErrNotSupported ); + } + else + { + const TDesC& title = playlistItem->ValueText(KMPXMediaGeneralTitle); + LOGGER_WRITE_1("KMPXMediaGeneralTitle: %S", &title); + aList.SetTitleL( title ); + } + + if ( playlistItem->IsSupported( KMPXMediaGeneralUri ) ) + { + const TDesC& uri = playlistItem->ValueText( KMPXMediaGeneralUri ); + aList.SetUrlL( uri ); + } + + CleanupStack::PopAndDestroy( playlistItem ); + + CMPXMedia* playlist = FetchPlaylistContentL( aPlaylistId ); + CleanupStack::PushL( playlist ); + + if ( !playlist->IsSupported(KMPXMediaArrayCount) ) + { + User::Leave(KErrNotSupported); + } + + // Number of references + TInt numOfRefs = *playlist->Value(KMPXMediaArrayCount); + LOGGER_WRITE_1("numOfRefs: %d", numOfRefs); + if ( numOfRefs ) + { + if (!playlist->IsSupported(KMPXMediaArrayContents)) + { + User::Leave(KErrNotSupported); + } + + const CMPXMediaArray* refArray = + playlist->Value(KMPXMediaArrayContents); + + // Import the references + for (TInt i=0;iIsSupported(KMPXMediaGeneralUri) ) + { + aList.AddItemL( refMedia->ValueText(KMPXMediaGeneralUri) ); + } + } + } + + CleanupStack::PopAndDestroy( playlist ); + + TRACE_FUNC_EXIT; + } + +// -------------------------------------------------------------------------- +// Fetch a playlist content +// -------------------------------------------------------------------------- +// +CMPXMedia* CMediaManager::FetchPlaylistContentL( TInt aId ) + { + TRACE_FUNC_ENTRY; + TMPXItemId id(aId); + + CMPXMedia* criteria = CMPXMedia::NewL(); + CleanupStack::PushL( criteria ); + criteria->SetTObjectValueL( + KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid ); + criteria->SetTObjectValueL( + KMPXMediaGeneralType, EMPXGroup ); + + // set search keys + criteria->SetTObjectValueL( + KMPXMediaGeneralCategory, EMPXSong ); + criteria->SetTObjectValueL( + KMPXMediaGeneralId, id ); + + // define attributes fetched + RArray songAttributes; + CleanupClosePushL(songAttributes); + songAttributes.AppendL(KMPXMediaGeneralId); + songAttributes.AppendL(KMPXMediaGeneralUri); + + // now find + CMPXMedia* result = iCollectionHelper->FindAllL( *criteria , songAttributes.Array() ); + CleanupStack::PopAndDestroy( &songAttributes ); + CleanupStack::PopAndDestroy( criteria ); + + TRACE_FUNC_EXIT; + return result; + } + + + // -------------------------------------------------------------------------- + // Find a playlist + // -------------------------------------------------------------------------- + // + CMPXMedia* CMediaManager::FindPlaylistL( TInt aUid ) + { + TRACE_FUNC_ENTRY; + CMPXMedia* criteria = CMPXMedia::NewL(); + CleanupStack::PushL( criteria ); + + criteria->SetTObjectValueL( + KMPXMediaGeneralType, EMPXItem ); + criteria->SetTObjectValueL( + KMPXMediaGeneralCategory, EMPXPlaylist ); + criteria->SetTObjectValueL( + KMPXMediaGeneralId, aUid ); + + // define attributes fetched + RArray playlistAttributes; + CleanupClosePushL(playlistAttributes); + playlistAttributes.AppendL(KMPXMediaGeneralId); + playlistAttributes.AppendL(KMPXMediaGeneralCollectionId); //test + playlistAttributes.AppendL(KMPXMediaGeneralTitle); + playlistAttributes.AppendL(KMPXMediaGeneralUri); + + // now find + CMPXMedia* foundList = 0; + foundList = iCollectionHelper->FindAllL( *criteria , playlistAttributes.Array() ); + CleanupStack::PopAndDestroy( &playlistAttributes ); + CleanupStack::PopAndDestroy( criteria ); + + CleanupStack::PushL( foundList ); + + if ( !foundList->IsSupported(KMPXMediaArrayCount) ) + { + LOGGER_WRITE("KMPXMediaArrayCount not supported"); + User::Leave( KErrNotSupported ); + } + + TInt foundItemCount = *foundList->Value(KMPXMediaArrayCount); + + CMPXMedia* playlist(NULL); + if ( foundItemCount ) + { + if ( !foundList->IsSupported(KMPXMediaArrayContents) ) + { + LOGGER_WRITE("KMPXMediaArrayContents not supported"); + User::Leave(KErrNotSupported); + } + + const CMPXMediaArray* foundArray = foundList->Value(KMPXMediaArrayContents); + + // get the first founded item + playlist = CMPXMedia::NewL(*(*foundArray)[0]); + } + else + { + User::Leave( KErrGeneral ); + } + + CleanupStack::PopAndDestroy( foundList ); + + TRACE_FUNC_EXIT; + return playlist; + } + +void CMediaManager::GetSongL( TInt aSongId, CSongItem& aSongItem ) + { + TRACE_FUNC_ENTRY; + TMPXItemId id(aSongId); + + RArray contentIDs; + CleanupClosePushL( contentIDs ); + contentIDs.AppendL( KMPXMediaIdMusic ); + contentIDs.AppendL( KMPXMediaIdGeneral ); + + CMPXMedia* criteria = CMPXMedia::NewL(contentIDs.Array()); + CleanupStack::PopAndDestroy( &contentIDs ); + CleanupStack::PushL(criteria); + + // set search keys + criteria->SetTObjectValueL( + KMPXMediaGeneralType, EMPXItem ); + criteria->SetTObjectValueL( + KMPXMediaGeneralCategory, EMPXSong ); + criteria->SetTObjectValueL( + KMPXMediaGeneralId, id ); + + // define attributes fetched + RArray songAttributes; + CleanupClosePushL(songAttributes); + + songAttributes.AppendL( KMPXMediaGeneralType ); + songAttributes.AppendL( KMPXMediaGeneralCategory ); + songAttributes.AppendL( KMPXMediaGeneralUri ); + songAttributes.AppendL( KMPXMediaGeneralId ); + songAttributes.AppendL( KMPXMediaGeneralTitle ); + songAttributes.AppendL( KMPXMediaGeneralMimeType ); + songAttributes.AppendL( KMPXMediaGeneralDuration ); + songAttributes.AppendL( KMPXMediaGeneralComment ); + + songAttributes.AppendL( KMPXMediaMusicArtist ); + songAttributes.AppendL( KMPXMediaMusicAlbum ); + songAttributes.AppendL( KMPXMediaMusicYear ); + songAttributes.AppendL( KMPXMediaMusicAlbumTrack ); + songAttributes.AppendL( KMPXMediaMusicGenre ); + songAttributes.AppendL( KMPXMediaMusicComposer ); + + // now find + CMPXMedia* result = 0; + TRAPD(err, result = iCollectionHelper->FindAllL( *criteria , songAttributes.Array() )); + CleanupStack::PopAndDestroy( &songAttributes ); + CleanupStack::PopAndDestroy( criteria ); + + if ( err ) + { + LOGGER_WRITE_1("FindAllL err: %d", err); + User::Leave( err ); + } + + CleanupStack::PushL( result ); + + if ( !result->IsSupported(KMPXMediaArrayCount) ) + { + LOGGER_WRITE("KMPXMediaArrayCount not supported"); + User::Leave(KErrNotSupported); + } + + if ( !result->IsSupported( KMPXMediaArrayContents ) ) + { + User::Leave(KErrNotSupported); + } + + const CMPXMediaArray* songsArray = + result->Value(KMPXMediaArrayContents); + if ( songsArray->Count() == 0 ) + { + User::Leave( KErrNotFound ); + } + const CMPXMedia* songMedia = (*songsArray)[0]; + + ReadSongAttributesL( *songMedia, aSongItem, ETrue ); + + CleanupStack::PopAndDestroy( result ); + + TRACE_FUNC_EXIT; + } + +CMPXMedia* CMediaManager::CreatePlaylistMediaL( const CPlaylistItem& aPlaylist ) + { + TRACE_FUNC_ENTRY; + RArray contentIDs; + contentIDs.AppendL(KMPXMediaIdGeneral); + + CMPXMedia* playlist = CMPXMedia::NewL( contentIDs.Array() ); + CleanupStack::PushL( playlist ); + contentIDs.Close(); + // add playlist info into the playlist media + playlist->SetTObjectValueL( + KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid ); + + // set playlist title + playlist->SetTextValueL( KMPXMediaGeneralTitle, aPlaylist.Title() ); + + // set type + playlist->SetTObjectValueL( KMPXMediaGeneralType, EMPXItem ); + + // set category + playlist->SetTObjectValueL( KMPXMediaGeneralCategory, EMPXPlaylist ); + + + TFileName playlistfile; + + TInt drive; + User::LeaveIfError( DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, drive) ); + TUint driveStatus( 0 ); + TInt err = DriveInfo::GetDriveStatus( iFs, drive, driveStatus ); + if ( !err && (driveStatus & DriveInfo::EDrivePresent) ) + { + User::LeaveIfError( PathInfo::GetRootPath( playlistfile, drive ) ); + LOGGER_WRITE_1("mmc playlistfile: %S", &playlistfile); + } + else + { + playlistfile = PathInfo::PhoneMemoryRootPath(); + LOGGER_WRITE_1("phone playlistfile: %S", &playlistfile); + } + + playlistfile.Append( KPlaylistPath ); + + // set location drive + TDriveUnit driveUnit( playlistfile ); + TPtrC driveName = driveUnit.Name(); + playlist->SetTextValueL( KMPXMediaGeneralDrive, driveName ); + + + TTime time; + time.HomeTime(); + playlistfile.AppendNum(time.Int64()); + playlistfile.Append(KMPXVirtualPlaylistExt); + + LOGGER_WRITE_1("playlistfile: %S", &playlistfile); + playlist->SetTextValueL( + KMPXMediaGeneralUri, playlistfile ); + + // set DbFlags to indicate that this is a virtual playlist + playlist->SetTObjectValueL(KMPXMediaGeneralFlags, + KMPXMediaGeneralFlagsSetOrUnsetBit | KMPXMediaGeneralFlagsIsVirtual); + + // create songs + CMPXMediaArray* medias = CreateMediaArrayLC( aPlaylist ); + // set medias + playlist->SetCObjectValueL( KMPXMediaArrayContents, medias ); + /// set media count + playlist->SetTObjectValueL( KMPXMediaArrayCount, medias->Count() ); + + CleanupStack::PopAndDestroy(medias); + CleanupStack::Pop(playlist); + + + TRACE_FUNC_EXIT; + return playlist; + } + +CMPXMediaArray* CMediaManager::CreateMediaArrayLC( const CPlaylistItem& aList ) + { + CMPXMediaArray* medias = CMPXMediaArray::NewL(); + CleanupStack::PushL( medias ); + // + // create entries + // + TInt itemCount = aList.ItemCount(); + for ( TInt i=0; iAddL( ptrUri, this ); + iWaitOngoing = ETrue; + LOGGER_WRITE("iWait.Start"); + iWait.Start(); + LOGGER_WRITE("continue.."); + + RArray contentIDs; + contentIDs.AppendL(KMPXMediaIdGeneral); + contentIDs.AppendL(KMPXMediaIdAudio); + contentIDs.AppendL(KMPXMediaIdMusic); + contentIDs.AppendL(KMPXMediaIdMTP); + + CMPXMedia* entry = CMPXMedia::NewL( contentIDs.Array() ); + CleanupStack::PushL( entry ); + contentIDs.Close(); + + entry->SetTObjectValueL( + KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid ); + + entry->SetTObjectValueL( + KMPXMediaGeneralType, EMPXItem ); + + entry->SetTObjectValueL( + KMPXMediaGeneralCategory, EMPXSong ); + + + entry->SetTextValueL( KMPXMediaGeneralUri, ptrUri ); + + // set location drive + TDriveUnit driveUnit( ptrUri ); + TPtrC driveName = driveUnit.Name(); + entry->SetTextValueL( KMPXMediaGeneralDrive, driveName ); + + medias->AppendL(entry); + CleanupStack::Pop(entry); + } + return medias; + } + +void CMediaManager::CreateNewPlaylistL( TInt& aNewUid, CPlaylistItem& aList ) + { + TRACE_FUNC_ENTRY; + + CMPXMedia* playlist = CreatePlaylistMediaL( aList ); + CleanupStack::PushL( playlist ); + iMediator->AddItemL( playlist ); + + if ( !playlist->IsSupported(KMPXMediaGeneralId) ) + { + LOGGER_WRITE("KMPXMediaGeneralId not supported"); + User::Leave( KErrNotSupported ); + } + else + { + // Extract the playlist id from the found object + TUint32 playlistId = *playlist->Value(KMPXMediaGeneralId); + LOGGER_WRITE_1("KMPXMediaGeneralId: %d", playlistId); + aNewUid = playlistId; + + if ( !playlist->IsSupported( KMPXMediaGeneralUri ) ) + { + // get url + const TDesC& uri = playlist->ValueText( KMPXMediaGeneralUri ); + aList.SetUrlL( uri ); + } + } + + CleanupStack::PopAndDestroy(playlist); + + TRACE_FUNC_EXIT; + } + +void CMediaManager::ReplacePlaylistL( TInt aPlaylistId, CPlaylistItem& aPlaylist ) + { + TRACE_FUNC_ENTRY; + CMPXMedia* playlist = CMPXMedia::NewL(); + CleanupStack::PushL( playlist ); + + // add playlist info into the playlist media + playlist->SetTObjectValueL( + KMPXMediaGeneralCollectionId, KMpxLocalCollectionUid ); + + // set type + playlist->SetTObjectValueL( KMPXMediaGeneralType, EMPXItem ); + + // set category + playlist->SetTObjectValueL( KMPXMediaGeneralCategory, EMPXPlaylist ); + + + + // find playlist uri + CMPXMedia* oldPlaylist = FindPlaylistL( aPlaylistId ); + CleanupStack::PushL( oldPlaylist ); + if ( !oldPlaylist->IsSupported(KMPXMediaGeneralUri) ) + { + User::Leave( KErrNotSupported ); + } + const TDesC& uri = oldPlaylist->ValueText( KMPXMediaGeneralUri ); + LOGGER_WRITE_1("uri: %S", &uri); + + playlist->SetTextValueL( + KMPXMediaGeneralUri, uri ); + + aPlaylist.SetUrlL( uri ); + + const TDesC& title = oldPlaylist->ValueText( KMPXMediaGeneralTitle ); + if ( title.Compare( aPlaylist.Title() ) != 0 ) + { + LOGGER_WRITE_1("title changed old: %S", &title); + LOGGER_WRITE_1("new title: %S", &aPlaylist.Title()); + // set playlist title + playlist->SetTextValueL( KMPXMediaGeneralTitle, aPlaylist.Title() ); + + // update title first + iMediator->SetItemL( playlist ); + } + + + CleanupStack::PopAndDestroy( oldPlaylist ); + + // update songs + CMPXMediaArray* songArray = CreateMediaArrayLC( aPlaylist ); + // set medias + playlist->SetCObjectValueL( KMPXMediaArrayContents, songArray ); + /// set media count + playlist->SetTObjectValueL( KMPXMediaArrayCount, songArray->Count() ); + + iMediator->SetItemL( playlist ); + + CleanupStack::PopAndDestroy( songArray ); + CleanupStack::PopAndDestroy( playlist ); + + TRACE_FUNC_EXIT; + } + + +void CMediaManager::DeletePlaylistL( TInt aPlaylistId ) + { + TRACE_FUNC_ENTRY; + + CMPXMedia* playlist = FindPlaylistL( aPlaylistId ); + CleanupStack::PushL( playlist ); + iCollection->Collection().RemoveL( *playlist ); + CleanupStack::PopAndDestroy( playlist ); + + TRACE_FUNC_EXIT; + } + +void CMediaManager::HandleAddFileCompleteL( TInt aErr ) + { + TRACE_FUNC_ENTRY; + LOGGER_WRITE_1("aErr: %d", aErr); + if ( iWaitOngoing ) + { + LOGGER_WRITE("AsyncStop"); + iWaitOngoing = EFalse; + iWait.AsyncStop(); + } + TRACE_FUNC_EXIT; + } + +void CMediaManager::ReadSongAttributesL( const CMPXMedia& aMedia, CSongItem& aSongItem, + TBool aReadFileDetails ) + { + if ( !aMedia.IsSupported(KMPXMediaGeneralUri) ) + { + LOGGER_WRITE("KMPXMediaGeneralUri not supported"); + User::Leave(KErrNotSupported); + } + + if ( !aMedia.IsSupported(KMPXMediaGeneralId) ) + { + LOGGER_WRITE("KMPXMediaGeneralId not supported"); + User::Leave(KErrNotSupported); + } + + aSongItem.SetId( *aMedia.Value(KMPXMediaGeneralId) ); + + const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri); + aSongItem.SetUriL( uri ); + + if ( aMedia.IsSupported(KMPXMediaGeneralTitle) ) + { + aSongItem.SetTitleL( aMedia.ValueText(KMPXMediaGeneralTitle) ); + } + + if ( aMedia.IsSupported(KMPXMediaGeneralMimeType) ) + { + aSongItem.SetMimeTypeL( aMedia.ValueText(KMPXMediaGeneralMimeType) ); + } + + if ( aMedia.IsSupported(KMPXMediaGeneralDuration) ) + { + aSongItem.SetDuration( aMedia.ValueTObjectL(KMPXMediaGeneralDuration) ); + } + + if ( aMedia.IsSupported(KMPXMediaMusicArtist) ) + { + aSongItem.SetArtistL( aMedia.ValueText(KMPXMediaMusicArtist) ); + } + + if ( aMedia.IsSupported(KMPXMediaMusicAlbum) ) + { + aSongItem.SetAlbumL( aMedia.ValueText(KMPXMediaMusicAlbum) ); + } + + if ( aMedia.IsSupported(KMPXMediaMusicYear) ) + { + TInt64 year = aMedia.ValueTObjectL( KMPXMediaMusicYear ); + TTime yearTime( year); + aSongItem.SetYear( yearTime.DateTime().Year() ); + } + + if ( aMedia.IsSupported(KMPXMediaMusicAlbumTrack) ) + { + aSongItem.SetAlbumTrack( *aMedia.Value(KMPXMediaMusicAlbumTrack) ); + } + + if ( aMedia.IsSupported(KMPXMediaMusicGenre) ) + { + const TDesC& genre = aMedia.ValueText(KMPXMediaMusicGenre); + aSongItem.SetGenreL( genre ); + } + + if ( aMedia.IsSupported(KMPXMediaMusicComposer) ) + { + aSongItem.SetComposerL( aMedia.ValueText(KMPXMediaMusicComposer) ); + } + + if ( aMedia.IsSupported(KMPXMediaGeneralComment) ) + { + aSongItem.SetCommentL( aMedia.ValueText(KMPXMediaGeneralComment) ); + } + + // Reading file timestamp and size is slow, read only if needed + if ( aReadFileDetails ) + { + TEntry fileEntry; + TInt err = iFs.Entry(uri,fileEntry); + if ( !err ) + { + aSongItem.SetModifiedTime( fileEntry.iModified ); + aSongItem.SetFileSize( fileEntry.iSize ); + } + } + + } + + +void CMediaManager::DoCancel() + { + TRACE_FUNC_ENTRY; + + delete iFoundedMedia; + iFoundedMedia = NULL; + iReadedItems = 0; + iItemsFound = 0; + TState state = iCurrentState; + iCurrentState = EIdle; + + switch (state) + { + case EReadingPlaylistCount: + case EEnumeratingPlaylists: + iObserver->RegisterAllPlayListsCompleted( KErrCancel ); + break; + + case EReadingSongCount: + case EEnumeratingSongs: + iObserver->RegisterAllSongsCompleted( KErrCancel ); + break; + default: + break; + } + + LOGGER_WRITE("signal cancel"); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrCancel ); + + TRACE_FUNC_EXIT; + } + +void CMediaManager::RunL() + { + TRACE_FUNC_ENTRY; + LOGGER_WRITE_1("iStatus.Int(): %d", iStatus.Int()) + TRequestStatus* status = &iStatus; + switch (iCurrentState) + { + case EReadingPlaylistCount: + //if ( !iCancel ) + // { + ReadPlaylistCountL(); + iReadedItems=0; + // next state + iCurrentState = EEnumeratingPlaylists; + SetActive(); + User::RequestComplete( status, KErrNone ); + /* } + else + { + LOGGER_WRITE("cancel"); + iCancel = EFalse; + delete iFoundedMedia; iFoundedMedia = NULL; + iReadedItems = 0; + iItemsFound = 0; + iCurrentState = EIdle; + iObserver->RegisterAllPlayListsCompleted( KErrCancel ); + }*/ + break; + + case EEnumeratingPlaylists: + //if ( !iCancel ) + // { + ReadPlaylistItemsL(); + if ( iReadedItems == iItemsFound ) + { + // all items readed + delete iFoundedMedia; + iFoundedMedia = NULL; + // next state + iCurrentState = EIdle; + iObserver->RegisterAllPlayListsCompleted( KErrNone ); + } + else + { + // not ready yet, continue same operation + SetActive(); + User::RequestComplete( status, KErrNone ); + } + /* } + else + { + // cancel + LOGGER_WRITE("cancel"); + iCancel = EFalse; + delete iFoundedMedia; iFoundedMedia = NULL; + iReadedItems = 0; + iItemsFound = 0; + iCurrentState = EIdle; + iObserver->RegisterAllPlayListsCompleted( KErrCancel ); + }*/ + break; + + case EReadingSongCount: + //if ( !iCancel ) + // { + ReadSongCountL(); + iReadedItems=0; + // next state + iCurrentState = EEnumeratingSongs; + SetActive(); + User::RequestComplete( status, KErrNone ); + /* } + else + { + LOGGER_WRITE("cancel"); + iCancel = EFalse; + delete iFoundedMedia; iFoundedMedia = NULL; + iReadedItems = 0; + iItemsFound = 0; + iCurrentState = EIdle; + iObserver->RegisterAllSongsCompleted( KErrCancel ); + }*/ + break; + + case EEnumeratingSongs: +// if ( !iCancel ) + // { + ReadSongItemsL(); + if ( iReadedItems == iItemsFound ) + { + // all items readed + delete iFoundedMedia; + iFoundedMedia = NULL; + // next state + iCurrentState = EIdle; + iObserver->RegisterAllSongsCompleted( KErrNone ); + } + else + { + // not ready yet, continue same operation + SetActive(); + User::RequestComplete( status, KErrNone ); + } + /* } + else + { + LOGGER_WRITE("cancel"); + iCancel = EFalse; + delete iFoundedMedia; iFoundedMedia = NULL; + iReadedItems = 0; + iItemsFound = 0; + iCurrentState = EIdle; + iObserver->RegisterAllSongsCompleted( KErrCancel ); + }*/ + break; + default: + break; + } + TRACE_FUNC_EXIT; + } + + +TInt CMediaManager::RunError( TInt aError ) + { + TRACE_FUNC_ENTRY; + LOGGER_WRITE_1("aError: %d", aError) + switch (iCurrentState) + { + case EReadingPlaylistCount: + case EEnumeratingPlaylists: + iObserver->RegisterAllPlayListsCompleted( aError ); + break; + case EReadingSongCount: + case EEnumeratingSongs: + iObserver->RegisterAllSongsCompleted( aError ); + break; + default: + LOGGER_WRITE("Unknown state!"); + break; + } + + TRACE_FUNC_EXIT; + return KErrNone; + } + +void CMediaManager::ReadPlaylistCountL() + { + TRACE_FUNC_ENTRY; + // Find all playlist files in the playlist DB + RArray contentIDs; + CleanupClosePushL( contentIDs ); + contentIDs.AppendL(KMPXMediaIdGeneral); + + CMPXMedia* searchMedia = CMPXMedia::NewL(contentIDs.Array()); + CleanupStack::PopAndDestroy( &contentIDs ); + CleanupStack::PushL(searchMedia); + + searchMedia->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); + searchMedia->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXPlaylist); + + RArray playlistAttributes; + CleanupClosePushL(playlistAttributes); + playlistAttributes.AppendL( KMPXMediaGeneralId ); + playlistAttributes.AppendL( KMPXMediaGeneralTitle ); + playlistAttributes.AppendL( KMPXMediaGeneralUri ); + + LOGGER_WRITE("find all"); + delete iFoundedMedia; iFoundedMedia=NULL; + iFoundedMedia = iCollectionHelper->FindAllL(*searchMedia, playlistAttributes.Array()); + CleanupStack::PopAndDestroy(&playlistAttributes); + CleanupStack::PopAndDestroy(searchMedia); + + if ( !iFoundedMedia->IsSupported(KMPXMediaArrayCount) ) + { + delete iFoundedMedia; iFoundedMedia=NULL; + User::Leave( KErrNotSupported ); + } + + iItemsFound = *iFoundedMedia->Value(KMPXMediaArrayCount); + + LOGGER_WRITE_1("playlists: %d", iItemsFound); + + if ( iItemsFound ) + { + if ( !iFoundedMedia->IsSupported(KMPXMediaArrayContents) ) + { + delete iFoundedMedia; iFoundedMedia=NULL; + iItemsFound = 0; + User::Leave(KErrNotSupported); + } + } + + TRACE_FUNC_EXIT; + } + +void CMediaManager::ReadPlaylistItemsL() + { + TRACE_FUNC_ENTRY; + TInt start = iReadedItems; + TInt end = start+iMaxPlaylistItemsToEnumerate; + if ( end >iItemsFound ) + { + end = iItemsFound; + } + + const CMPXMediaArray* foundArray = iFoundedMedia->Value(KMPXMediaArrayContents); + + for (TInt i = start; i < end; i++) + { + LOGGER_WRITE_1("read playlistItem: %d", i); + CMPXMedia* playlistMedia = CMPXMedia::NewL(*(*foundArray)[i]); + CleanupStack::PushL( playlistMedia ); + + // Append playlist to item array + RegisterPlaylistL( *playlistMedia ); + + CleanupStack::PopAndDestroy( playlistMedia ); + iReadedItems++; + } + + TRACE_FUNC_EXIT; + } + + + +void CMediaManager::ReadSongCountL() + { + TRACE_FUNC_ENTRY; + + RArray contentIDs; + CleanupClosePushL( contentIDs ); + contentIDs.AppendL( KMPXMediaIdGeneral ); + contentIDs.AppendL( KMPXMediaIdMusic ); + + CMPXMedia* criteria = CMPXMedia::NewL(contentIDs.Array()); + CleanupStack::PopAndDestroy( &contentIDs ); + CleanupStack::PushL(criteria); + + criteria->SetTObjectValueL( KMPXMediaGeneralType, EMPXItem ); + criteria->SetTObjectValueL( KMPXMediaGeneralCategory, EMPXSong ); + + // define attributes fetched + RArray songAttributes; + CleanupClosePushL(songAttributes); + + songAttributes.AppendL( KMPXMediaGeneralType ); + songAttributes.AppendL( KMPXMediaGeneralCategory ); + songAttributes.AppendL( KMPXMediaGeneralUri ); + songAttributes.AppendL( KMPXMediaGeneralId ); + songAttributes.AppendL( KMPXMediaGeneralTitle ); + songAttributes.AppendL( KMPXMediaGeneralMimeType ); + songAttributes.AppendL( KMPXMediaGeneralDuration ); + songAttributes.AppendL( KMPXMediaGeneralComment ); + + songAttributes.AppendL( KMPXMediaMusicArtist ); + songAttributes.AppendL( KMPXMediaMusicAlbum ); + songAttributes.AppendL( KMPXMediaMusicYear ); + songAttributes.AppendL( KMPXMediaMusicAlbumTrack ); + songAttributes.AppendL( KMPXMediaMusicGenre ); + songAttributes.AppendL( KMPXMediaMusicComposer ); + + delete iFoundedMedia; + iFoundedMedia = NULL; + // now find + LOGGER_WRITE("FindAllL"); + iFoundedMedia = iCollectionHelper->FindAllL( *criteria , songAttributes.Array() ); + + LOGGER_WRITE("FindAllL ok"); + CleanupStack::PopAndDestroy( &songAttributes ); + CleanupStack::PopAndDestroy( criteria ); + + + if ( !iFoundedMedia->IsSupported(KMPXMediaArrayCount) ) + { + LOGGER_WRITE("KMPXMediaArrayCount not supported"); + delete iFoundedMedia; + iFoundedMedia = NULL; + iItemsFound = 0; + User::Leave(KErrNotSupported); + } + + // Number of references + iItemsFound = *iFoundedMedia->Value(KMPXMediaArrayCount); + LOGGER_WRITE_1("songs: %d", iItemsFound); + if ( iItemsFound ) + { + if (!iFoundedMedia->IsSupported(KMPXMediaArrayContents)) + { + delete iFoundedMedia; + iFoundedMedia = NULL; + iItemsFound = 0; + User::Leave(KErrNotSupported); + } + } + + TRACE_FUNC_EXIT; + } + +void CMediaManager::ReadSongItemsL() + { + TRACE_FUNC_ENTRY; + + TInt start = iReadedItems; + TInt end = start+iMaxSongItemsToEnumerate; + if ( end >iItemsFound ) + { + end = iItemsFound; + } + + const CMPXMediaArray* foundArray = iFoundedMedia->Value(KMPXMediaArrayContents); + + TKeyArrayFix key( iKey ); + // Import the references + for (TInt i = start; i < end; i++) + { + //LOGGER_WRITE_1("read songitem: %d",i); + const CMPXMedia* refMedia = (*foundArray)[i]; + + CSongItem* song = CSongItem::NewLC(); + + ReadSongAttributesL( *refMedia, *song, EFalse ); + TSnapshotItem snapshotItem( song->Id(), KAllSongsFolderId ); + snapshotItem.SetItemHash( *song, iHasher ); + + iSnapshotArray->InsertIsqL( snapshotItem, key ); + + CleanupStack::PopAndDestroy( song ); + iReadedItems++; + } + TRACE_FUNC_EXIT; + }