diff -r 000000000000 -r a2952bb97e68 mmappcomponents/collectionhelper/src/mpxcollectioncachedhelper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmappcomponents/collectionhelper/src/mpxcollectioncachedhelper.cpp Thu Dec 17 08:55:47 2009 +0200 @@ -0,0 +1,1116 @@ +/* +* 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: Extended collection helper with an internal caching array +* Version : %version: da1mmcf#27.1.12 % +* +*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "mpxcollectioncachedhelper.h" +#include "mpxcollectionhelpercommon.h" +#include + +// CONSTANTS +const TInt KCacheCount = 10; + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +CMPXCollectionCachedHelper::CMPXCollectionCachedHelper() : +#ifdef RD_MPX_COLLECTION_CACHE + CMPXCollectionHelperImp(EFalse),iNotInCache(ETrue), iHitFoundMedia(0), + iNotHitInCache(0), iLookingInCache(0),iLookingInUnknowCache(0), +#endif //RD_MPX_COLLECTION_CACHE + iMetadataExtractor(NULL) + { + } + + +// --------------------------------------------------------------------------- +// 2nd Phase Constructor +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::ConstructL() + { + MPX_DEBUG1("CMPXCollectionCachedHelper::ConstructL <--"); + iCache = CMPXMediaArray::NewL(); + CMPXCollectionHelperImp::ConstructL(); + +#ifdef RD_MPX_COLLECTION_CACHE + MPX_DEBUG1("CMPXCollectionCachedHelper::ConstructL Todd advancedcache"); + // cache for unknown artist + TMPXItemId artistId = NULL; + TRAPD(err, artistId = GetArtistIdL( KNullDesC(), iMusicCollectionId )); + if ( err || artistId == (TMPXItemId)0 ) + { + MPX_DEBUG2("CMPXCollectionCachedHelper::ConstructL no known artist id %d", err); + } + else + { + // Get songs that belong to the unknown artist + GetSongsL( artistId, iMusicCollectionId, ETrue ); + } +#endif //RD_MPX_COLLECTION_CACHE + User::LeaveIfError( iFs.Connect() ); + User::LeaveIfError( iAppArc.Connect() ); + iMetadataExtractor = CMPXMetadataExtractor::NewL( iFs, iAppArc, iSupportedTypes); + MPX_DEBUG1("CMPXCollectionCachedHelper::ConstructL -->"); + } + + +// --------------------------------------------------------------------------- +// Two-Phased Constructor +// --------------------------------------------------------------------------- +// +CMPXCollectionCachedHelper* CMPXCollectionCachedHelper::NewL() + { + CMPXCollectionCachedHelper* self = CMPXCollectionCachedHelper::NewLC(); + CleanupStack::Pop( self ); + return self; + } + + +// --------------------------------------------------------------------------- +// Two-Phased Constructor +// --------------------------------------------------------------------------- +// +CMPXCollectionCachedHelper* CMPXCollectionCachedHelper::NewLC() + { + CMPXCollectionCachedHelper* self = new( ELeave ) CMPXCollectionCachedHelper(); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CMPXCollectionCachedHelper::~CMPXCollectionCachedHelper() + { + Commit(); + delete iFoundMedia; +#ifdef RD_MPX_COLLECTION_CACHE + if ( iCachedArtistArray ) + { + delete iCachedArtistArray; + } + if ( iCachedUnknownArtistArray ) + { + delete iCachedUnknownArtistArray; + } +#endif //RD_MPX_COLLECTION_CACHE + delete iCache; + iOp.Close(); + if (iMetadataExtractor) + { + delete iMetadataExtractor; + } + iFs.Close(); + iAppArc.Close(); + iSupportedTypes.ResetAndDestroy(); + } + +// --------------------------------------------------------------------------- +// Add a media object +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::AddL( CMPXMedia* aMedia ) + { + MPX_FUNC("CMPXCollectionCachedHelper::::AddL"); + // Commit when we have cached more than a set amount + // + if( iCache->Count() >= KCacheCount) + { + Commit(); + } + + // Extract album art from the file + iMetadataExtractor->ExtractAlbumArtL( aMedia ); + + CMPXMedia* copy = CMPXMedia::NewL( *aMedia ); + CleanupStack::PushL( copy ); + iCache->AppendL( copy ); // ownership x-fer + CleanupStack::Pop( copy ); + iOp.AppendL( EAdd ); + } + +// --------------------------------------------------------------------------- +// Remove a media object +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::RemoveL( const TDesC& aFile, + TMPXGeneralCategory aItemCat ) + { + MPX_FUNC("CMPXCollectionCachedHelper::RemoveL"); + MPX_DEBUG3("aFile %S, category %d", &aFile, aItemCat); + + Commit(); + + ::InitializeCollectionPluginsL( *iCollectionUtil ); + + // + // ask harvester to remove the file if any of the following is true: + // 1) removing a song + // 2) removing a playlist scanned through file system. + // + // There are 3 types of playlists. The ones created from the device + // are virtual playlists which have file extension .vir. There are + // no physical playlist files associated with them; hence not + // registered with harvester. For virtual playlists, IsPlaylistL + // will return EFalse because there is not a playlist plugin that + // deals with .vir playlist files. + // + // The ones synced from PC through MTP have file extension .pla. + // There are 0-byte .pla files associated with them but they + // are not registered with harvester either. IsPlaylistL will also + // return EFalse because there is not a playlist plugin that deals + // with .pla. + // + // The 3rd type of playlists is .m3u on the file system. They are + // added to the collection through file scan and registered with + // harvester. IsPlaylistL will return ETrue. + // + // For now virtual playlists and synced playlists are assumed to + // be in the music collection for now until there is a generic way + // resolving collections aside from using file extension or UID. + // + TInt collection(iMusicCollectionId.iUid); + if (aItemCat == EMPXSong || iHvsUtility->IsPlaylistL(aFile)) + { + // Remove from the harvester + collection = iHvsUtility->RemoveFileL( aFile ); + } + + // Remove from the collection + // Construct a CMPXMedia object with URI and collection + // + RArray contID; + CleanupClosePushL( contID ); + contID.AppendL( KMPXMediaIdGeneral ); + CMPXMedia* media = CMPXMedia::NewL( contID.Array() ); + CleanupStack::PopAndDestroy(&contID); + CleanupStack::PushL( media ); + + media->SetTextValueL( KMPXMediaGeneralUri, aFile ); + media->SetTObjectValueL( KMPXMediaGeneralCollectionId, TUid::Uid( collection ) ); + media->SetTObjectValueL( KMPXMediaGeneralType, EMPXItem ); + media->SetTObjectValueL( KMPXMediaGeneralCategory, aItemCat ); + + // set up remove media command + CMPXCommand* command = CMPXMedia::NewL(); + CleanupStack::PushL(command); + + command->SetTObjectValueL( + KMPXCommandGeneralId, KMPXCommandIdCollectionRemoveMedia); + command->SetTObjectValueL( + KMPXCommandGeneralDoSync, ETrue); + command->SetTObjectValueL( + KMPXCommandGeneralCollectionId, collection); + command->SetCObjectValueL( + TMPXAttribute(KMPXCommandIdCollectionRemoveMedia, EMPXCommandCollectionRemoveMedia), + media); + command->SetTObjectValueL( + TMPXAttribute(KMPXCommandIdCollectionRemoveMedia, EMPXCommandCollectionRemoveMediaDeleteRecord), ETrue); + + // send sync remove media command + iCollectionUtil->Collection().CommandL(*command); + + // + // return command should contain error attribute + // + if (!command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionRemoveMedia, EMPXCommandCollectionRemoveMediaError))) + { + User::Leave(KErrAbort); + } + + // + // abandon operation if an error occured cleaning up deleted medias from the collection + // + TInt error = + command->ValueTObjectL( + TMPXAttribute(KMPXCommandIdCollectionRemoveMedia, EMPXCommandCollectionRemoveMediaError)); + User::LeaveIfError(error); + + // + // reset found media if it's been deleted + // + if (iFoundMedia && + iFoundMedia->ValueText(KMPXMediaGeneralUri).CompareF(aFile) == 0) + { + delete iFoundMedia; + iFoundMedia = NULL; + } + + CleanupStack::PopAndDestroy(2, media ); // command and media + } + +// --------------------------------------------------------------------------- +// Remove a media object +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::CleanupDeletedMediasL() + { + MPX_FUNC("CMPXCollectionCachedHelper::CleanupDeletedMediasL"); + + Commit(); + + ::InitializeCollectionPluginsL( *iCollectionUtil ); + + // + // set up the command to send to the collection + // + CMPXCommand* command = CMPXMedia::NewL(); + CleanupStack::PushL(command); + + command->SetTObjectValueL( + KMPXCommandGeneralId, KMPXCommandIdCollectionCleanupDeletedMedias); + command->SetTObjectValueL( + KMPXCommandGeneralDoSync, ETrue); + command->SetTObjectValueL( + KMPXCommandGeneralCollectionId, iMusicCollectionId.iUid); + + // send sync cleanup command + iCollectionUtil->Collection().CommandL(*command); + + // + // return command should contain error attribute + // + if (!command->IsSupported(TMPXAttribute(KMPXCommandIdCollectionCleanupDeletedMedias, EMPXCommandCollectionCleanupError))) + { + User::Leave(KErrAbort); + } + + // + // abandon operation if an error occured cleaning up deleted medias from the collection + // + TInt error = + command->ValueTObjectL( + TMPXAttribute(KMPXCommandIdCollectionCleanupDeletedMedias, EMPXCommandCollectionCleanupError)); + User::LeaveIfError(error); + + CleanupStack::PopAndDestroy(command); + } + +// --------------------------------------------------------------------------- +// Update a media object +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::SetL( CMPXMedia*& aMedia ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::::SetL <--"); + + const TDesC& newUri = aMedia->ValueText( KMPXMediaGeneralUri ); + TInt count( iCache->Count() ); + + // Take advantage that MTP always try to access the most recent item + // + CMPXMedia* media( NULL ); + for( TInt i=count-1; i>=0; --i ) + { + const TDesC& uri = iCache->AtL(i)->ValueText( KMPXMediaGeneralUri ); + if( newUri.CompareF( uri ) == 0 ) + { + MPX_DEBUG2("Found existing media, index %i", i); + media = iCache->AtL(i); + break; + } + } + + // Not found in the array + if( !media ) + { + CMPXMedia* copy = CMPXMedia::NewL( *aMedia ); + CleanupStack::PushL( copy ); + iCache->AppendL( copy ); // ownership x-fer + CleanupStack::Pop( copy ); + iOp.AppendL( ESet ); + } + else + { + // Update existing media object already in the array + // + DoAppendGeneralL( *aMedia, *media ); + DoAppendMusicL( *aMedia, *media ); + DoAppendAudioL( *aMedia, *media ); + DoAppendDRML( *aMedia, *media ); + DoAppendContainerL( *aMedia, *media ); + DoAppendMTPL( *aMedia, *media ); + } + MPX_DEBUG1("CMPXCollectionCachedHelper::::SetL -->"); + } + +// --------------------------------------------------------------------------- +// Renames a file +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::RenameL( const TDesC& aOldUri, + const TDesC& aNewUri, + TMPXGeneralCategory aItemCat ) + { + TInt count = iCache->Count(); + + // Take advantage that MTP always try to access the most recent item + // + CMPXMedia* media( NULL ); + for( TInt i=count-1; i>=0; --i ) + { + const TDesC& uri = iCache->AtL(i)->ValueText( KMPXMediaGeneralUri ); + if( aOldUri.CompareF( uri ) == 0 ) + { + MPX_DEBUG2("Found existing media, index %i", i); + media = iCache->AtL(i); + break; + } + } + + // Not found in the array + if( !media ) + { + Commit(); + CMPXCollectionHelperImp::RenameL(aOldUri, aNewUri, aItemCat); + } + else + { + // Update existing media object already in the array + // + media->SetTextValueL(KMPXMediaGeneralUri, aNewUri); + } + + if (iFoundMedia && + iFoundMedia->ValueText(KMPXMediaGeneralUri).CompareF(aOldUri) == 0) + { + iFoundMedia->SetTextValueL(KMPXMediaGeneralUri, aNewUri); + } + } + + +#ifdef RD_MPX_COLLECTION_CACHE +// --------------------------------------------------------------------------- +// Gets the media object of the supplied attributes +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::GetSongL( const TDesC& aFile, + TMPXGeneralCategory aItemCat, TUid aCollectionUId ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::GetSongL <--"); + RArray attributes; + CleanupClosePushL(attributes); + + attributes.AppendL( + TMPXAttribute(KMPXMediaIdGeneral, + EMPXMediaGeneralTitle | EMPXMediaGeneralDate | + EMPXMediaGeneralDuration | EMPXMediaGeneralComment | + EMPXMediaGeneralUri )); + attributes.AppendL( + TMPXAttribute(KMPXMediaIdMusic, + EMPXMediaMusicArtist | EMPXMediaMusicAlbum | + EMPXMediaMusicAlbumTrack | EMPXMediaMusicComposer | + EMPXMediaMusicYear | EMPXMediaMusicGenre)); + + attributes.AppendL(KMPXMediaAudioAudioAll); + attributes.AppendL(KMPXMediaMTPAll); + + delete iFoundMedia; + iFoundMedia = NULL; + iFoundMedia = CMPXCollectionHelperImp::GetL( aFile, attributes.Array(), aItemCat ); + if ( !iFoundMedia ) + { + User::Leave(KErrNotFound); + } + iFoundMedia->SetTObjectValueL( + KMPXMediaGeneralCollectionId, aCollectionUId ); + + CleanupStack::PopAndDestroy(&attributes); + //MPX_DEBUG1("Artist name ="); + //RDebug::RawPrint(iFoundMedia->ValueText( KMPXMediaMusicArtist)); + MPX_DEBUG1("CMPXCollectionCachedHelper::GetSongL -->"); + } + + + + +// --------------------------------------------------------------------------- +// Gets the artist id for the media object +// --------------------------------------------------------------------------- +// +TMPXItemId CMPXCollectionCachedHelper::GetArtistIdL( const TDesC& aArtist, + TUid aCollectionUId ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::GetArtistIdL <--"); + CMPXMedia* search = CMPXMedia::NewL(); + CleanupStack::PushL(search); + search->SetTObjectValueL(KMPXMediaGeneralType, EMPXItem); + search->SetTObjectValueL(KMPXMediaGeneralCategory, EMPXArtist); + search->SetTObjectValueL( KMPXMediaGeneralCollectionId, aCollectionUId ); + search->SetTextValueL( KMPXMediaGeneralTitle, aArtist ); + + RArray attributes; + CleanupClosePushL(attributes); + attributes.AppendL(KMPXMediaGeneralId); + + CMPXMedia* result = + CMPXCollectionHelperImp::FindAllL(*search, attributes.Array()); + CleanupStack::PopAndDestroy(&attributes); + CleanupStack::PopAndDestroy(search); + CleanupStack::PushL(result); + const CMPXMediaArray* results = + result->Value(KMPXMediaArrayContents); + if( !results ) + { + User::Leave( KErrNoMemory ); + } + + TMPXItemId artistId = 0; + if ( !results->Count() || aArtist == KNullDesC ) + { + CleanupStack::PopAndDestroy(result); + return TMPXItemId(0); + } + + artistId = results->AtL(0)->ValueTObjectL(KMPXMediaGeneralId); + CleanupStack::PopAndDestroy(result); + + + MPX_DEBUG1("CMPXCollectionCachedHelper::GetArtistIdL -->"); + return artistId; + } + + + +// --------------------------------------------------------------------------- +// Gets the artist id for the media object +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::GetSongsL( TMPXItemId aArtistId, + TUid aCollectionUId, TBool aUnknownArtist ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::GetSongsLL <--"); + + RArray attributes; + CleanupClosePushL(attributes); + + if ((aArtistId == (TMPXItemId)0) || aUnknownArtist ) + { + CleanupStack::PopAndDestroy(&attributes); + return; + } + + attributes.AppendL( + TMPXAttribute(KMPXMediaIdGeneral, + EMPXMediaGeneralTitle | EMPXMediaGeneralDate | + EMPXMediaGeneralDuration | EMPXMediaGeneralComment | + EMPXMediaGeneralUri )); + attributes.AppendL( + TMPXAttribute(KMPXMediaIdMusic, + EMPXMediaMusicArtist | EMPXMediaMusicAlbum | + EMPXMediaMusicAlbumTrack | EMPXMediaMusicComposer | + EMPXMediaMusicYear | EMPXMediaMusicGenre)); + + attributes.AppendL(KMPXMediaAudioAudioAll); + attributes.AppendL(KMPXMediaMTPAll); + + CMPXMedia* search = CMPXMedia::NewL(); + CleanupStack::PushL( search ); + search->SetTObjectValueL( KMPXMediaGeneralType, EMPXGroup); + search->SetTObjectValueL( KMPXMediaGeneralCategory, EMPXSong ); + search->SetTObjectValueL( KMPXMediaGeneralCollectionId, aCollectionUId ); + search->SetTObjectValueL( KMPXMediaGeneralId, aArtistId ); + + // Search in synch mode + CMPXMedia* result = CMPXCollectionHelperImp::FindAllL( *search, attributes.Array() ); + CleanupStack::PopAndDestroy( search ); + CleanupStack::PopAndDestroy(&attributes); + + CleanupStack::PushL(result); + if( result->IsSupported( KMPXMediaArrayContents ) ) + { + if ( !aUnknownArtist ) + { // cache for known artist + if ( iCachedArtistArray ) + { + delete iCachedArtistArray; + iCachedArtistArray = NULL; + } + CMPXMediaArray* ary = result->Value(KMPXMediaArrayContents); + iCachedArtistArray = CMPXMediaArray::NewL(*ary); + MPX_DEBUG2("Known Artist Array count()=%d", iCachedArtistArray->Count()); + } + else // cache for unknown artist + { + if ( iCachedUnknownArtistArray ) + { + delete iCachedUnknownArtistArray; + iCachedUnknownArtistArray = NULL; + } + CMPXMediaArray* ary = result->Value(KMPXMediaArrayContents); + iCachedUnknownArtistArray = CMPXMediaArray::NewL(*ary); + MPX_DEBUG2("Unknown Artist Array count()=%d", iCachedUnknownArtistArray->Count()); + } + } + + + CleanupStack::PopAndDestroy(result); + + MPX_DEBUG1("CMPXCollectionCachedHelper::GetSongsLL -->"); + } + +#endif //RD_MPX_COLLECTION_CACHE + + +// --------------------------------------------------------------------------- +// Gets the attributes of some media object +// --------------------------------------------------------------------------- +// +const CMPXMedia& CMPXCollectionCachedHelper::GetL( const TDesC& aFile, + TMPXGeneralCategory aItemCat ) + { + +#ifdef RD_MPX_COLLECTION_CACHE + Commit(); + + if (aItemCat != EMPXSong && aItemCat != EMPXPlaylist) + { + User::Leave(KErrArgument); + } + + MPX_DEBUG1("CMPXCollectionCachedHelper::GetL (advanced cache version) <--"); + MPX_DEBUG2("aFile %S", &aFile); + + // If the iFoundMedia is cached + if ( iFoundMedia ) + { + // and if asking for the same file, just return. + if ( iFoundMedia->ValueText(KMPXMediaGeneralUri).CompareF(aFile) == 0 ) + { + iHitFoundMedia++; + return *iFoundMedia; + } + // and if not asking for the same file, seach through cacahed array. + // It probably cached in the cached artist array + else if ( iCachedArtistArray && iCachedArtistArray->Count() ) + { + TInt count( iCachedArtistArray->Count() ); + iNotInCache = ETrue; + iLookingInCache++; + MPX_DEBUG1("CMPXCollectionCachedHelper::GetL looking into cache <--"); + for( TInt i=0; iAtL(i); + //RDebug::Printf("Checking... begin"); + //RDebug::RawPrint(m.ValueText(KMPXMediaGeneralUri)); + if ( m.ValueText(KMPXMediaGeneralUri).CompareF(aFile) == 0 ) + { + delete iFoundMedia; + iFoundMedia = NULL; + iFoundMedia = CMPXMedia::NewL( m ); + iNotInCache = EFalse; + MPX_DEBUG1("CMPXCollectionCachedHelper::GetL found in cache <--"); + break; + } + } + // if not in cached artist array, try with unknown array + if ( iNotInCache && iCachedUnknownArtistArray && iCachedUnknownArtistArray->Count() ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::GetL looking into unknown cache <--"); + iLookingInUnknowCache++; + count = iCachedUnknownArtistArray->Count(); + for( TInt i=0; iAtL(i); + if ( m.ValueText(KMPXMediaGeneralUri).CompareF(aFile) == 0 ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::GetL found unknown cache <--"); + delete iFoundMedia; + iFoundMedia = NULL; + iFoundMedia = CMPXMedia::NewL( m ); + iNotInCache = EFalse; + break; + } + } + } + } + } + + + + // No cache or not finding anything in the cached artist arraies + // it got to search the song in db and also create cache for the new artist + if ( !iFoundMedia || !iCachedArtistArray || iNotInCache ) + { + MPX_DEBUG4("CMPXCollectionCachedHelper::GetL looking in db <-- iFoundMedia=%x iCachedArtistArray=%x, iNotInCache=%d", iFoundMedia, iCachedArtistArray, iNotInCache); + TInt col(iMusicCollectionId.iUid); + if (aItemCat == EMPXSong || iHvsUtility->IsPlaylistL(aFile)) + { + TRAPD(err, col = iHvsUtility->FindCollectionIdL( aFile )); + if (err != KErrNone) + { + MPX_DEBUG2("CMPXCollectionCachedHelper::GetL error $", err); + } + } + // to get single song that matches the supplied URI + + GetSongL(aFile, aItemCat, TUid::Uid(col)); + + if ( aItemCat == EMPXPlaylist ) + { + return *iFoundMedia; // no need to cache for playlist request + } + + iNotHitInCache++; + + // Get Artist Id + TMPXItemId artistId = (TMPXItemId)0; + if ( iFoundMedia->IsSupported(KMPXMediaMusicArtist) + && iFoundMedia->ValueText(KMPXMediaMusicArtist).Length() ) + { + TRAPD(err, artistId = GetArtistIdL( + iFoundMedia->ValueText(KMPXMediaMusicArtist), TUid::Uid(col) )); + if ( err ) + { + artistId = GetArtistIdL( KNullDesC(), TUid::Uid(col) ); + } + } + else + { + artistId = GetArtistIdL( KNullDesC(), TUid::Uid(col) ); + } + // Get songs that belongs to the same artist id + GetSongsL( artistId, TUid::Uid(col), EFalse ); + } + + MPX_DEBUG1("CMPXCollectionCachedHelper::GetL -->"); + return *iFoundMedia; + +#else //RD_MPX_COLLECTION_CACHE + + MPX_DEBUG1("CMPXCollectionCachedHelper::GetL <--"); + + if (aItemCat != EMPXSong && aItemCat != EMPXPlaylist) + { + User::Leave(KErrArgument); + } + + // Do reverse search on cache + for( TInt i = iCache->Count()-1; i >= 0; --i ) + { + CMPXMedia* media = iCache->AtL(i); + if( media && + media->ValueText(KMPXMediaGeneralUri).CompareF(aFile) == 0 ) + { + return *media; + } + } + + if (!iFoundMedia || + iFoundMedia->ValueText(KMPXMediaGeneralUri).CompareF(aFile) != 0) + { + delete iFoundMedia; + iFoundMedia = NULL; + + Commit(); + + RArray attributes; + CleanupClosePushL(attributes); + + attributes.AppendL( + TMPXAttribute(KMPXMediaIdGeneral, + EMPXMediaGeneralTitle | EMPXMediaGeneralDate | + EMPXMediaGeneralDuration | EMPXMediaGeneralComment | + EMPXMediaGeneralUri )); + attributes.AppendL( + TMPXAttribute(KMPXMediaIdMusic, + EMPXMediaMusicArtist | EMPXMediaMusicAlbum | + EMPXMediaMusicAlbumTrack | EMPXMediaMusicComposer | + EMPXMediaMusicYear | EMPXMediaMusicGenre)); + attributes.AppendL(KMPXMediaAudioAudioAll); + attributes.AppendL(KMPXMediaMTPAll); + + iFoundMedia = CMPXCollectionHelperImp::GetL( aFile, attributes.Array(), aItemCat ); + + CleanupStack::PopAndDestroy(&attributes); + } + MPX_DEBUG1("CMPXCollectionCachedHelper::GetL -->"); + return *iFoundMedia; + +#endif //RD_MPX_COLLECTION_CACHE + + } + +// --------------------------------------------------------------------------- +// Find some media +// --------------------------------------------------------------------------- +// +CMPXMedia* CMPXCollectionCachedHelper::FindAllL( CMPXMedia& aCriteria, + const TArray& aAttrs ) + { + Commit(); + + return CMPXCollectionHelperImp::FindAllL( aCriteria, aAttrs ); + } + +// --------------------------------------------------------------------------- +// Close function to destroy this object +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::Close() + { +#ifdef RD_MPX_COLLECTION_CACHE + MPX_DEBUG2("mpx perf result iHitFoundMedia=%d", iHitFoundMedia); + MPX_DEBUG2("mpx pref result iNotHitInCache=%d", iNotHitInCache); + MPX_DEBUG2("mpx perf result iLookingInCache=%d", iLookingInCache); + MPX_DEBUG2("mpx perf result iLookingInUnknowCache=%d", iLookingInUnknowCache); +#endif //RD_MPX_COLLECTION_CACHE + delete this; + } + +// --------------------------------------------------------------------------- +// Commits all transactions left in the helper +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::Commit() + { + MPX_DEBUG2("CMPXCollectionCachedHelper::Commit %d <--", iCache->Count()); + TInt error( KErrNotFound ); + TInt count( iCache->Count() ); + + for( TInt i=0; iValueText(KMPXMediaGeneralUri).CompareF(media->ValueText(KMPXMediaGeneralUri)) == 0) + { + TRAP_IGNORE( + DoAppendGeneralL( *media, *iFoundMedia ); + DoAppendMusicL( *media, *iFoundMedia ); + DoAppendAudioL( *media, *iFoundMedia ); + DoAppendDRML( *media, *iFoundMedia ); + DoAppendContainerL( *media, *iFoundMedia ); + DoAppendMTPL( *media, *iFoundMedia ); + ); + } + + iCache->Remove(0); + iOp.Remove(0); + } + + MPX_DEBUG1("CMPXCollectionCachedHelper::Commit -->"); + } + +// --------------------------------------------------------------------------- +// Copies general media information +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::DoAppendGeneralL( CMPXMedia& aSrc, + CMPXMedia& aDestination ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::DoAppendGeneralL <--"); + + // Note: Only a subset used by MTP... + // + TUint atts = aSrc.AttributesSet( KMPXMediaIdGeneral ); + if( atts&EMPXMediaGeneralUri ) // text + { + aDestination.SetTextValueL( KMPXMediaGeneralUri, + aSrc.ValueText(KMPXMediaGeneralUri ) + ); + } + if( atts&EMPXMediaGeneralDrive ) // text + { + aDestination.SetTextValueL( KMPXMediaGeneralDrive, + aSrc.ValueText(KMPXMediaGeneralDrive ) + ); + } + if( atts&EMPXMediaGeneralTitle ) // text + { + aDestination.SetTextValueL( KMPXMediaGeneralTitle, + aSrc.ValueText(KMPXMediaGeneralTitle ) + ); + } + if( atts&EMPXMediaGeneralComment ) //text + { + aDestination.SetTextValueL( KMPXMediaGeneralComment, + aSrc.ValueText(KMPXMediaGeneralComment ) + ); + } + if( atts&EMPXMediaGeneralMimeType ) //text + { + aDestination.SetTextValueL( KMPXMediaGeneralMimeType, + aSrc.ValueText(KMPXMediaGeneralMimeType ) + ); + } + if( atts&EMPXMediaGeneralDate ) // TInt64 + { + aDestination.SetTObjectValueL( KMPXMediaGeneralDate, + aSrc.ValueTObjectL(KMPXMediaGeneralDate ) + ); + } + if( atts&EMPXMediaGeneralDuration ) // TInt + { + aDestination.SetTObjectValueL( KMPXMediaGeneralDuration, + aSrc.ValueTObjectL( KMPXMediaGeneralDuration ) + ); + } + if( atts&EMPXMediaGeneralSynchronized ) // TBool + { + aDestination.SetTObjectValueL( KMPXMediaGeneralSynchronized, + aSrc.ValueTObjectL( KMPXMediaGeneralSynchronized ) + ); + } + if( atts&EMPXMediaGeneralDeleted ) // TBool + { + aDestination.SetTObjectValueL( KMPXMediaGeneralDeleted, + aSrc.ValueTObjectL( KMPXMediaGeneralDeleted ) + ); + } + if( atts&EMPXMediaGeneralModified ) // TBool + { + aDestination.SetTObjectValueL( KMPXMediaGeneralModified, + aSrc.ValueTObjectL( KMPXMediaGeneralModified ) + ); + } + if( atts&KMPXMediaGeneralFlags.iAttributeId ) // TUint + { + aDestination.SetTObjectValueL( KMPXMediaGeneralFlags, + aSrc.ValueTObjectL( KMPXMediaGeneralFlags ) + ); + } + MPX_DEBUG1("CMPXCollectionCachedHelper::DoAppendGeneralL -->"); + } + +// --------------------------------------------------------------------------- +// Copies music media information +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::DoAppendMusicL( CMPXMedia& aSrc, + CMPXMedia& aDestination ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::DoAppendMusicL <--"); + TUint atts = aSrc.AttributesSet( KMPXMediaIdMusic ); + + // Note: Only a subset used by MTP... + // + if( atts&EMPXMediaMusicArtist ) // Text + { + aDestination.SetTextValueL( KMPXMediaMusicArtist, + aSrc.ValueText(KMPXMediaMusicArtist ) + ); + } + if( atts&EMPXMediaMusicAlbum ) // Text + { + aDestination.SetTextValueL( KMPXMediaMusicAlbum, + aSrc.ValueText(KMPXMediaMusicAlbum ) + ); + } + if( atts&EMPXMediaMusicAlbumTrack ) // Text + { + aDestination.SetTextValueL( KMPXMediaMusicAlbumTrack, + aSrc.ValueText(KMPXMediaMusicAlbumTrack ) + ); + } + if( atts&EMPXMediaMusicComposer ) // Text + { + aDestination.SetTextValueL( KMPXMediaMusicComposer, + aSrc.ValueText(KMPXMediaMusicComposer ) + ); + } + if( atts&EMPXMediaMusicYear ) // TInt64 + { + aDestination.SetTObjectValueL( KMPXMediaMusicYear, + aSrc.ValueTObjectL( KMPXMediaMusicYear ) + ); + } + if( atts&EMPXMediaMusicGenre ) // Text + { + aDestination.SetTextValueL( KMPXMediaMusicGenre, + aSrc.ValueText(KMPXMediaMusicGenre ) + ); + } + if( atts&EMPXMediaMusicRating ) // TInt + { + aDestination.SetTObjectValueL( KMPXMediaMusicRating, + aSrc.ValueTObjectL( KMPXMediaMusicRating ) + ); + } + MPX_DEBUG1("CMPXCollectionCachedHelper::DoAppendMusicL -->"); + } + +// --------------------------------------------------------------------------- +// Copies Audio media information +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::DoAppendAudioL( CMPXMedia& aSrc, + CMPXMedia& aDestination ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::DoAppendAudioL <--"); + TUint atts = aSrc.AttributesSet( KMPXMediaIdAudio ); + if( atts&EMPXMediaAudioBitrate ) // TInt + { + aDestination.SetTObjectValueL( KMPXMediaAudioBitrate, + aSrc.ValueTObjectL( KMPXMediaAudioBitrate ) + ); + } + if( atts&EMPXMediaAudioSamplerate ) // TInt + { + aDestination.SetTObjectValueL( KMPXMediaAudioSamplerate, + aSrc.ValueTObjectL( KMPXMediaAudioSamplerate ) + ); + } + if( atts&EMPXMediaAudioNumberOfChannels ) // TInt + { + aDestination.SetTObjectValueL( KMPXMediaAudioNumberOfChannels, + aSrc.ValueTObjectL( KMPXMediaAudioNumberOfChannels ) + ); + } + if( atts&EMPXMediaAudioCodec ) // TInt + { + aDestination.SetTObjectValueL( KMPXMediaAudioAudioCodec, + aSrc.ValueTObjectL( KMPXMediaAudioAudioCodec ) + ); + } + MPX_DEBUG1("CMPXCollectionCachedHelper::DoAppendAudioL -->"); + } + +// --------------------------------------------------------------------------- +// Copies DRM media information +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::DoAppendDRML( CMPXMedia& aSrc, + CMPXMedia& aDestination ) + { + MPX_DEBUG1("CMPXCollectionCachedHelper::DoAppendDRML <--"); + TUint atts = aSrc.AttributesSet( KMPXMediaIdDrm ); + + // Note: Only a subset used by MTP... + // + if( atts&EMPXMediaDrmProtected ) // TBool + { + aDestination.SetTObjectValueL( KMPXMediaDrmProtected, + aSrc.ValueTObjectL( KMPXMediaDrmProtected ) + ); + } + if( atts&EMPXMediaDrmRightsStatus ) // TInt + { + aDestination.SetTObjectValueL( KMPXMediaDrmRightsStatus, + aSrc.ValueTObjectL( KMPXMediaDrmRightsStatus ) + ); + } + MPX_DEBUG1("CMPXCollectionCachedHelper::DoAppendDRML -->"); + } + +// --------------------------------------------------------------------------- +// Copies array information +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::DoAppendContainerL( CMPXMedia& aSrc, + CMPXMedia& aDestination ) + { + MPX_FUNC("CMPXCollectionCachedHelper::DoAppendContainerL"); + + TUint atts = aSrc.AttributesSet( KMPXMediaIdContainer ); + + if( atts&EMPXMediaArrayContents ) + { + const CMPXMediaArray* medias = + aSrc.Value( KMPXMediaArrayContents ); + if( !medias ) + { + User::Leave( KErrNoMemory ); + } + + aDestination.SetCObjectValueL( + KMPXMediaArrayContents, + const_cast(medias)); + } + if( atts&EMPXMediaArrayCount ) // TInt + { + aDestination.SetTObjectValueL( KMPXMediaArrayCount, + aSrc.ValueTObjectL( KMPXMediaArrayCount ) + ); + } + } + +// --------------------------------------------------------------------------- +// Copies mtp information +// --------------------------------------------------------------------------- +// +void CMPXCollectionCachedHelper::DoAppendMTPL( CMPXMedia& aSrc, + CMPXMedia& aDestination ) + { + MPX_FUNC("CMPXCollectionCachedHelper::DoAppendMTPL"); + + TUint atts = aSrc.AttributesSet( KMPXMediaIdMTP ); + + if( atts&KMPXMediaMTPDrmStatus.iAttributeId) + { + TUint16 val = aSrc.ValueTObjectL(KMPXMediaMTPDrmStatus); + aDestination.SetTObjectValueL( KMPXMediaMTPDrmStatus, val ); + } + } + +// END OF FILE