--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mpxplugins/serviceplugins/collectionplugins/mpxsqlitedbhgplugin/src/mpxdbhandler.cpp Wed Sep 01 12:32:02 2010 +0100
@@ -0,0 +1,3310 @@
+/*
+* Copyright (c) 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: This class is used by db plugin for all database related
+* functionality. The main responsibilities are:
+*
+*/
+
+
+// INCLUDE FILES
+#include <bautils.h>
+#ifdef RD_MULTIPLE_DRIVE
+#include <driveinfo.h>
+#include <pathinfo.h>
+#endif //RD_MULTIPLE_DRIVE
+
+#include <mpxcollectiondbhgres.rsg>
+#include <mpxmediageneraldefs.h>
+#include <mpxmediacontainerdefs.h>
+#include <mpxmediamusicdefs.h>
+#include <mpxmediaaudiodefs.h>
+#include <mpxmedia.h>
+#include <mpxmediaarray.h>
+#include <mpxcollectionpath.h>
+#include <mpxlog.h>
+
+#include "mpxresource.h"
+#include "mpxdbcommonutil.h"
+
+#include "mpxdbutil.h"
+#include "mpxcollectiondbdef.h"
+#include "mpxdbpluginqueries.h"
+#include "mpxcollectiondbmanager.h"
+#include "mpxdbplaylist.h"
+#include "mpxdbplaylistsongs.h"
+#include "mpxdbcategory.h"
+#include "mpxdbauxiliary.h"
+#include "mpxdbautoplaylist.h"
+#include "mpxdbhandler.h"
+#include "mpxdbartist.h"
+#include "mpxdbalbum.h"
+#include "mpxdbgenre.h"
+#include "mpxdbcomposer.h"
+
+// CONSTANTS
+_LIT(KMPXVirtualPlaylistExt, ".vir");
+static const TInt KMaxOpInTransaction = 100;
+
+const TInt KSqlDbCorrupted = -321;
+
+#if defined (__MTP_PROTOCOL_SUPPORT)
+
+#include <centralrepository.h>
+
+// MTP CenRep Key UID
+const TUid KMPXMtpSettings = {0x101FFC53};
+// MTP CenRep Key for Delete contents
+const TUint32 KMPXMtpSaveDeletedRecordFlag = 0x00000001;
+
+#endif
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXDbHandler* CMPXDbHandler::NewL(
+ RFs& aFs,
+ CMPXResource& aResource)
+ {
+ MPX_FUNC("CMPXDbHandler::NewL");
+ CMPXDbHandler* self = CMPXDbHandler::NewLC(aFs, aResource);
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXDbHandler* CMPXDbHandler::NewLC(
+ RFs& aFs,
+ CMPXResource& aResource)
+ {
+ MPX_FUNC("CMPXDbHandler::NewLC");
+ CMPXDbHandler* self = new (ELeave) CMPXDbHandler(aFs, aResource);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CMPXDbHandler::~CMPXDbHandler()
+ {
+ MPX_FUNC("CMPXDbHandler::~CMPXDbHandler");
+
+ delete iAutoPlaylist;
+
+ delete iDbMusic;
+ delete iDbPlaylist;
+ delete iDbArtist;
+ delete iDbAlbum;
+ delete iDbGenre;
+ delete iDbComposer;
+ delete iDbAuxiliary;
+ delete iDbManager;
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ delete iDbAbstractAlbum;
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+ delete iMimeTypes;
+ delete iExtensions;
+ delete iExtensionsMime;
+ delete iExtensionsDrm;
+
+ iDbDrives.Close();
+ }
+
+// ----------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that might leave
+// ----------------------------------------------------------------------------
+//
+CMPXDbHandler::CMPXDbHandler(
+ RFs& aFs,
+ CMPXResource& aResource) :
+ iFs(aFs),
+ iResource(aResource)
+ {
+ MPX_FUNC("CMPXDbHandler::CMPXDbHandler");
+ }
+
+// ----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::ConstructL()
+ {
+ MPX_FUNC("CMPXDbHandler::ConstructL");
+
+ iMimeTypes = iResource.ReadDesCArrayL(R_MC_MIME_TYPES);
+ iExtensions = iResource.ReadDesCArrayL(R_MC_MUSIC_FILE_EXTENSIONS);
+ iExtensionsMime = iResource.ReadDesCArrayL(R_MC_FILE_EXTENSIONS_MIME);
+ iExtensionsDrm = iResource.ReadDesCArrayL(R_MC_FILE_EXTENSIONS_DRM);
+
+ // make sure all databases are created and valid
+ iDbManager = CMPXCollectionDbManager::NewL(iFs);
+
+ CDesCArrayFlat* musicFolders =
+#ifdef RD_MULTIPLE_DRIVE
+ GetMusicFoldersL();
+#else
+ iResource.ReadDesCArrayL(R_MC_DEFAULT_MUSIC_FOLDERS);
+#endif
+
+ // create the music folders and initialize iDbDrives
+ CleanupStack::PushL(musicFolders);
+ ProcessMusicFoldersL(*musicFolders);
+ CleanupStack::PopAndDestroy(musicFolders);
+
+ // Create the db infrastructure,
+ //
+ iDbMusic = CMPXDbMusic::NewL(*iDbManager, iResource, *this);
+ iDbPlaylist = CMPXDbPlaylist::NewL(*iDbManager, *this);
+ iDbArtist = CMPXDbArtist::NewL(*iDbManager, EMPXArtist, *this);
+ iDbAlbum = CMPXDbAlbum::NewL(*iDbManager, EMPXAlbum, *this);
+ iDbGenre = CMPXDbGenre::NewL(*iDbManager, EMPXGenre);
+ iDbComposer = CMPXDbComposer::NewL(*iDbManager, EMPXComposer);
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ iDbAbstractAlbum = CMPXDbAbstractAlbum::NewL(*iDbManager, EMPXAbstractAlbum, iFs);
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+ iAutoPlaylist = CMPXDbAutoPlaylist::NewL(*iDbManager, iFs, iResource);
+ iDbAuxiliary = CMPXDbAuxiliary::NewL(*iDbManager);
+
+ MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
+
+ // If KErrCorrupt is returned, a database file was found to be corrupted
+ // and was replaced with a new one. The db plugin can ignore this error and continue
+ // because a new db file was successfully created in a subsequent retry.
+ if ((err != KErrNone) && (err != KErrCorrupt) && (err != KErrDiskFull))
+ {
+ // leave to signal the caller that there was an error why creating and opening
+ // one or more of the databases
+ User::Leave(err);
+ }
+ else if (err == KErrDiskFull)
+ {
+ iOutOfDisk = ETrue;
+ }
+ else
+ {
+ // do nothing
+ }
+
+ // Verify the volume ids of each drive matches the database
+ MPX_TRAP(err,VerifyVolumeIdL());
+ if ((err != KErrNone) && (err != KErrDiskFull))
+ {
+ // leave to signal the caller that there was an error why creating and opening
+ // one or more of the databases
+ User::Leave(err);
+ }
+ else if (err == KErrDiskFull)
+ {
+ iOutOfDisk = ETrue;
+ }
+
+//#ifdef _DEBUG
+// iDbManager->PrintDatabaseL(); // PREQ2536 the files sqlrowsetutil.h and sqlrowsetutil.cpp has been removed
+//#endif
+
+ MPX_DEBUG2("CMPXDbHandler::ConstructL DbCount[%d]", iDbManager->DatabaseCount());
+ }
+
+// ----------------------------------------------------------------------------
+// Add song to collection
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::AddSongL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray* aMessageArray)
+ {
+ MPX_FUNC("CMPXDbHandler::AddSongL");
+
+ BeginTransactionL();
+ TUint32 songId(0);
+ MPX_TRAPD(err, songId = DoAddSongL(aMedia,aMessageArray));
+
+ if (iOutOfDisk && (err == KErrNotFound))
+ {
+ err = KErrDiskFull;
+ }
+ EndTransactionL(err);
+
+ return songId;
+ }
+
+// ----------------------------------------------------------------------------
+// Add song to collection with no database transaction
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::AddSongWithNoTransactionL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray* aMessageArray)
+ {
+ MPX_FUNC("CMPXDbHandler::AddSongWithNoTransactionL");
+
+ TUint32 songId(0);
+ MPX_TRAPD(err, songId = DoAddSongL(aMedia,aMessageArray));
+
+ if (iOutOfDisk && (err == KErrNotFound))
+ {
+ err = KErrDiskFull;
+ }
+ User::LeaveIfError(err);
+
+ return songId;
+ }
+
+// ----------------------------------------------------------------------------
+// Add playlist to collection
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::AddPlaylistL(
+ const CMPXMedia& aMedia)
+ {
+ MPX_FUNC("CMPXDbHandler::AddPlaylistL");
+
+ BeginTransactionL();
+ TUint32 playlistId(0);
+ MPX_TRAPD(err, playlistId = DoAddPlaylistL(aMedia));
+ EndTransactionL(err);
+
+ return playlistId;
+ }
+
+// ----------------------------------------------------------------------------
+// Add song to playlist
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::AddSongToPlaylistL(
+ const CMPXMedia& aMedia)
+ {
+ MPX_FUNC("CMPXDbHandler::AddSongToPlaylistL");
+
+ BeginTransactionL();
+ TUint32 playlistId(0);
+ MPX_TRAPD(err, playlistId = DoAddSongToPlaylistL(aMedia));
+ EndTransactionL(err);
+
+ return playlistId;
+ }
+
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+// ----------------------------------------------------------------------------
+// Add AbstractAlbum to collection
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::AddAbstractAlbumL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray* aMessageArray)
+ {
+ MPX_FUNC("CMPXDbHandler::AddAbstractAlbumL");
+
+ BeginTransactionL();
+ TBool newRecord(EFalse);
+ TInt err(KErrNone);
+
+ TDriveUnit drive(aMedia.ValueText(KMPXMediaGeneralUri));
+ TPtrC uri(aMedia.ValueText(KMPXMediaGeneralUri).Left(KMCMaxTextLen));
+ TPtrC name(aMedia.ValueText(KMPXMediaGeneralTitle).Left(KMCMaxTextLen));
+ TPtrC albumartist(aMedia.ValueText(KMPXMediaMusicAlbumArtist).Left(KMCMaxTextLen));
+
+ //only insert to AbstractAlbum table when it is new item
+ TUint32 abstractAlbumId(MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXAbstractAlbum, uri, EFalse));
+
+ newRecord = !iDbAbstractAlbum->CategoryItemExistsL(drive, abstractAlbumId);
+
+ if (newRecord)
+ {
+ MPX_TRAP(err, abstractAlbumId = iDbAbstractAlbum->AddItemL(uri, name, albumartist, drive, newRecord, EFalse));
+ if (iOutOfDisk && (err == KErrNotFound))
+ {
+ err = KErrDiskFull;
+ }
+ if (aMessageArray)
+ {
+ MPXDbCommonUtil::AddItemChangedMessageL(*aMessageArray, abstractAlbumId, EMPXItemInserted,
+ EMPXAbstractAlbum, KDBPluginUid);
+ }
+ }
+ EndTransactionL(err);
+
+ return abstractAlbumId;
+ }
+
+// ----------------------------------------------------------------------------
+// Update abstractalbum info to AbstractAlbum table and all songs which associate
+// with AbstractAlbum in the collection
+// ----------------------------------------------------------------------------
+//
+CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::UpdateAbstractAlbumL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::UpdateAbstractAlbumL");
+
+ CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
+ TUint32 itemId(0);
+ if (aMedia.IsSupported(KMPXMediaGeneralUri))
+ {
+ const TDesC& uri(aMedia.ValueText (KMPXMediaGeneralUri));
+ TDriveUnit drive(aMedia.ValueText(KMPXMediaGeneralUri));
+
+ //get Id based on new uri
+ itemId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXAbstractAlbum, uri, EFalse);
+ if (!itemId)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ //if updating to new item, need do renaming for AbstractAlbum: delete old one and insert a new entry to AbstractAlbum table
+ //if a new item, need update songs associated and renaming albstractalbum table
+ if (aMedia.IsSupported(KMPXMediaGeneralId))
+ {
+ MPX_DEBUG1("CMPXDbHandler::UpdateAbstractAlbumL, rename case");
+
+ BeginTransactionL();
+ //get old id, for renaming
+ TInt err(KErrNone);
+ TUint32 oldId = (aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
+ if (oldId && (oldId != itemId) ) //pass the old UID for renaming, do not care if new itemId exist or not
+ {
+ //get old Uri based on old Id
+ HBufC* oldUri = iDbAbstractAlbum->GetUriL(oldId);
+ CleanupStack::PushL(oldUri);
+
+ //add and update new item to AbstractAlbum table
+ //old existing item field values need to be saved and added when adding new item
+ MPX_TRAP(err, itemId = iDbAbstractAlbum->AddUpdatedItemL(oldId, uri ));
+
+ if (iOutOfDisk && (err == KErrNotFound))
+ {
+ err = KErrDiskFull;
+ }
+
+ MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, itemId, EMPXItemInserted,
+ EMPXAbstractAlbum, KDBPluginUid);
+
+ //find and update all songs associated with oldId
+ RArray<TMPXAttribute> songAttributes;
+ CleanupClosePushL(songAttributes);
+ songAttributes.AppendL(KMPXMediaGeneralId);
+
+ CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
+ CleanupStack::PushL(mediaArray);
+
+ //get all songs associated
+ MPX_TRAP(err, iDbMusic->GetAllSongsForAbstractAlbumL(oldId, songAttributes.Array(), *mediaArray));
+ if (err == KErrNotFound)
+ {
+ // Leave with KErrNotFound
+ MPX_DEBUG1("CMPXDbHandler::UpdateAbstractAlbumL, leave with not found");
+ User::Leave(KErrNotFound);
+ }
+
+ TInt count(mediaArray->Count());
+ MPX_DEBUG2("CMPXDbHandler::UpdateAbstractAlbumL, [%d] songs associated", count);
+ //go through all songs for updating
+ for (TInt i = 0; i < count; i++)
+ {
+ CMPXMedia* song = mediaArray->AtL(i);
+ song->SetTextValueL(KMPXMediaMusicAlbumArtFileName, uri );
+ visibleChange = UpdateSongL(*song, aItemChangedMessages);
+ }
+ CleanupStack::PopAndDestroy(mediaArray);
+ CleanupStack::PopAndDestroy(&songAttributes);
+
+ //rename TN
+ iDbAbstractAlbum->HandleTNL(*oldUri, uri, 0);
+ CleanupStack::PopAndDestroy(oldUri);
+ }
+ EndTransactionL(err);
+ }//renaming
+
+ //check if abstractAlbum exist in ABSTRACTALBUM table before update it
+ else if (iDbAbstractAlbum->CategoryItemExistsL(drive, itemId))
+ {
+ //support updating Name, AlbumArtist fields for AbstractAlbum table
+ iDbAbstractAlbum->UpdateItemL(itemId, aMedia, drive, &aItemChangedMessages);
+ }
+ }
+ return visibleChange;
+ }
+
+// ----------------------------------------------------------------------------
+// Update all songs which associate with AbstractAlbum to new AbstractAlbum info
+// in the collection
+// ----------------------------------------------------------------------------
+//
+CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::UpdateSongsAbstractAlbumInfoL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::UpdateSongsAbstractAlbumInfoL");
+ const TDesC& uri(aMedia.ValueText (KMPXMediaGeneralUri));
+ //need to update songs information to music table
+ CMPXMediaArray* mediaArray = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
+ User::LeaveIfNull(mediaArray);
+ TInt count(mediaArray->Count());
+ CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
+ for (TInt i = 0; i < count; i++)
+ {
+ CMPXMedia* mediaSong = mediaArray->AtL(i);
+ mediaSong->SetTextValueL(KMPXMediaMusicAlbumArtFileName, uri );
+ visibleChange = UpdateSongL(*mediaSong, aItemChangedMessages);
+ }
+ return visibleChange;
+ }
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+
+// ----------------------------------------------------------------------------
+// Update a song in the collection
+// ----------------------------------------------------------------------------
+//
+CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::UpdateSongL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::UpdateSongL");
+
+ BeginTransactionL();
+ CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
+ MPX_TRAPD(err, visibleChange = DoUpdateSongL(aMedia, aItemChangedMessages));
+ EndTransactionL(err);
+ return visibleChange;
+ }
+
+// ----------------------------------------------------------------------------
+// Update a playlist in the collection
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::UpdatePlaylistL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray& aMessageArray)
+ {
+ MPX_FUNC("CMPXDbHandler::UpdatePlaylistL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, DoUpdatePlaylistL(aMedia, aMessageArray));
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Updates the playlist songs
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::UpdatePlaylistSongsL(
+ const CMPXMedia& aMedia,
+ CMPXMessage& aMessage)
+ {
+ MPX_FUNC("CMPXDbHandler::UpdatePlaylistSongsL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, DoUpdatePlaylistSongsL(aMedia, aMessage));
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Reorder a song in a playlist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::ReorderPlaylistL(
+ const TMPXItemId& aPlaylistId,
+ const TMPXItemId& aSongId,
+ TUint aOriginalOrdinal,
+ TUint aNewOrdinal,
+ CMPXMessage& aMessage)
+ {
+ MPX_DEBUG5("-->CMPXDbHandler::ReorderPlaylistL(0x%x, 0x%x, %d, %d)",
+ aPlaylistId.iId2, aSongId.iId2, aOriginalOrdinal, aNewOrdinal);
+
+ BeginTransactionL();
+ MPX_TRAPD(err, DoReorderPlaylistL(aPlaylistId, aSongId, aOriginalOrdinal, aNewOrdinal, aMessage));
+ EndTransactionL(err);
+ MPX_DEBUG2("<--CMPXDbHandler::ReorderPlaylistL() error=%d", err);
+ }
+
+// ----------------------------------------------------------------------------
+// Remove the entire music collection database
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RemoveEntireCollectionL()
+ {
+ MPX_FUNC("CMPXDbHandler::RemoveEntireCollectionL");
+ BeginTransactionL();
+ MPX_TRAPD(err, iDbManager->RecreateAllDatabasesL());
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Delete a song from collection
+// The function notifies collection model to perform deletion
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RemoveSongL(
+ TUint32 aSongId,
+ CDesCArray& aUriArray,
+ CMPXMessageArray& aItemChangedMessages,
+ TBool aDeleteRecord)
+ {
+ MPX_FUNC("CMPXDbHandler::RemoveSongL");
+
+ MPX_TRAPD(err, DoRemoveSongL(aSongId, aUriArray, aItemChangedMessages, aDeleteRecord));
+
+ MPX_TRAP(err, DoRemoveSongFromPlaylistL(aSongId,aItemChangedMessages));
+
+ }
+
+// ----------------------------------------------------------------------------
+// Removes a category of songs from the music collection,
+// and its corresponding category in the lookup table
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RemoveSongsMatchingCategoryL(
+ TMPXGeneralCategory aCategory,
+ TUint32 aCategoryId,
+ CDesCArray& aUriArray,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingCategoryL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, DoRemoveSongsMatchingCategoryL(aCategory, aCategoryId, aUriArray, aItemChangedMessages));
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------------------------------------
+// Delete songs for the specified artist and album from collection
+// The function notifies collection model to perform deletion
+// ----------------------------------------------------------------------------------------------------------
+//
+void CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL(
+ TUint32 aArtistId,
+ TUint32 aAlbumId,
+ CDesCArray& aUriArray,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, DoRemoveSongsMatchingArtistAndAlbumL(aArtistId, aAlbumId, aUriArray,
+ aItemChangedMessages));
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Remove all playlists from collection
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RemoveAllPlaylistsL()
+ {
+ MPX_FUNC("CMPXDbHandler::RemoveAllPlaylistsL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, DoRemoveAllPlaylistsL());
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Remove specified playlist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RemovePlaylistL(
+ TUint32 aPlaylistId,
+ CDesCArray& aUriArray,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::RemovePlaylistL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, DoRemovePlaylistL(aPlaylistId, aUriArray, aItemChangedMessages));
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Remove song from playlist songs table
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RemoveSongFromPlaylistL(
+ TUint32 aPlaylistId,
+ const TMPXItemId& aSongId,
+ TInt aOrdinal,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::RemoveSongFromPlaylistL");
+ MPX_DEBUG5("CMPXDbHandler::RemoveSongFromPlaylistL(playlist 0x%x, songId [0x%x,0x%x], ordinal %d)",
+ aPlaylistId, aSongId.iId1, aSongId.iId2, aOrdinal);
+
+ MPX_TRAPD(err, DoRemoveSongFromPlaylistL(aPlaylistId, aSongId, aOrdinal, aItemChangedMessages));
+ if ( err && InTransaction() )
+ {
+ // only end transaction if there's an error
+ EndTransactionL( err );
+ }
+ }
+
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+// ----------------------------------------------------------------------------
+// Remove specified abstractalbum
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RemoveAbstractAlbumL(
+ TUint32 aAbstractAlbumId,
+ CMPXMessageArray& aItemChangedMessages, TBool aFileDeleted)
+ {
+ MPX_FUNC("CMPXDbHandler::RemoveAbstractAlbumL");
+ iDbAbstractAlbum->RemoveAbstractAlbumL(aAbstractAlbumId, aItemChangedMessages, aFileDeleted);
+ }
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+
+// ----------------------------------------------------------------------------
+// Cleanup records marked as deleted. This is designated for MTP to clean up records marked as deleted
+// at the end of its session.
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::CleanupDeletedRecordsL()
+ {
+ MPX_FUNC("CMPXDbHandler::CleanupDeletedRecordsL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, DoCleanupDeletedRecordsL());
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Read all songs and cache them into an array ordered by song name
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAllSongsL(
+ CMPXMediaArray* aMediaArray,
+ const TArray<TMPXAttribute>& aAttrs)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllSongsL");
+ iDbMusic->GetAllSongsL(aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Read a limited # of songs and cache them into an array ordered by song name
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAllSongsLimitedL(const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray, TInt aLimit)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllSongsLimitedL");
+ iDbMusic->GetAllSongsLimitedL( aAttrs, aMediaArray, aLimit );
+ }
+
+// ----------------------------------------------------------------------------
+// Read all songs and cache them into an array ordered by song name
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongsInBlockL(
+ CMPXMediaArray* aMediaArray,
+ const TArray<TMPXAttribute>& aAttrs,
+ TPtrC aTitle,
+ TUint aNumOfSongs,
+ TBool aAsc)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongsInBlockL");
+ iDbMusic->GetSongsInBlockL(aAttrs, *aMediaArray, aTitle, aNumOfSongs, aAsc);
+ }
+
+// ----------------------------------------------------------------------------
+// Read songs at a particular offset
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongsAtOffsetL( CMPXMediaArray* aMediaArray,
+ const TArray<TMPXAttribute>& aAttrs,
+ TInt aOffset,
+ TInt aCount )
+ {
+ MPX_DEBUG1("CMPXDbHandler::GetSongsAtOffsetL <--");
+ iDbMusic->GetSongsAtOffsetL( *aMediaArray, aAttrs, aOffset, aCount );
+ }
+
+// ----------------------------------------------------------------------------
+// Get all songs matching the given artist ID
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongsMatchingArtistL(
+ TUint aArtistId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongsMatchingArtistL");
+ iDbMusic->GetSongsForArtistL(aArtistId, aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all songs matching the given album ID
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongsMatchingAlbumL(
+ TUint aAlbumId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongsMatchingAlbumL");
+ iDbMusic->GetSongsForAlbumL(aAlbumId, aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------------------------------------
+// Get all songs matching the given artist and album ID
+// ----------------------------------------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongsMatchingArtistAndAlbumL(
+ TUint aArtistId,
+ TUint aAlbumId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongsMatchingArtistAndAlbumL");
+ iDbMusic->GetSongsForArtistAndAlbumL(aArtistId, aAlbumId, aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all songs matching the given genre ID
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongsMatchingGenreL(
+ TUint aGenreId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongsMatchingGenreL");
+ iDbMusic->GetSongsForGenreL(aGenreId, aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all songs matching the given composer ID
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongsMatchingComposerL(
+ TUint aComposerId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongsMatchingComposerL");
+ iDbMusic->GetSongsForComposerL(aComposerId, aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all songs that belong to the given playlist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongsMatchingPlaylistL(
+ TUint aPlaylistId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongsMatchingPlaylistL");
+ GetPlaylistSongsL(aPlaylistId, aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get song matching the given song ID
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongL(
+ TUint32 aSongId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMedia& aMedia)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongL");
+ iDbMusic->GetSongL(aSongId, aAttrs, aMedia);
+ }
+
+// ----------------------------------------------------------------------------
+// GetSongL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetSongL(
+ TUint32 aSongId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongL");
+
+ CMPXMedia* media = CMPXMedia::NewL();
+ CleanupStack::PushL(media);
+
+ GetSongL(aSongId, aAttrs, *media);
+ aMediaArray.AppendL(*media);
+
+ CleanupStack::PopAndDestroy(media);
+ }
+
+// ----------------------------------------------------------------------------
+// Get song matching the given song ID and playlist ID
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetPlaylistSongL(
+ TUint32 aSongId,
+ TUint32 aPlaylistId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMedia& aMedia)
+ {
+ MPX_DEBUG3("-->CMPXDbHandler::GetPlaylistSongL songId[0x%x] playlistId[0x%x]", aSongId, aPlaylistId);
+
+ // complete the song information from the Music table
+ MPX_TRAPD(err, iDbMusic->GetSongL(aSongId, aAttrs, aMedia));
+
+ //
+ // song not found in Music table
+ //
+ if (err == KErrNotFound)
+ {
+ //
+ // Leave with KErrNotFound if one of the following is true:
+ // 1) the requested song is in an auto playlist. Since auto-playlist isn't
+ // stored in playlist tables, we won't be able to retrieve info elsewhere
+ // 2) the requested song is in a user playlist but we cannot find the song
+ // info from playlist tables either
+ //
+ if (EMPXNoAutoPlaylist != iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) ||
+ !iDbPlaylist->Songs().GetSongL(aPlaylistId, aSongId, aAttrs, aMedia))
+ {
+ User::Leave(KErrNotFound);
+ }
+ }
+
+ //
+ // Unable to read information from Music table
+ //
+ else
+ {
+ // ignore the error if KErrNotFound
+ User::LeaveIfError(err);
+ }
+ MPX_DEBUG1("<--CMPXDbHandler::GetPlaylistSongL");
+ }
+
+// ----------------------------------------------------------------------------
+// GetPlaylistSongL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetPlaylistSongL(
+ TUint32 aSongId,
+ TUint32 aPlaylistId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetPlaylistSongL");
+
+ CMPXMedia* media = CMPXMedia::NewL();
+ CleanupStack::PushL(media);
+
+ GetPlaylistSongL(aSongId, aPlaylistId, aAttrs, *media);
+ aMediaArray.AppendL(*media);
+
+ CleanupStack::PopAndDestroy(media);
+ }
+
+// ----------------------------------------------------------------------------
+// Get song matching the given URI
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::GetSongIdMatchingUriL(
+ const TDesC& aUri)
+ {
+ MPX_FUNC("CMPXDbHandler::GetSongIdMatchingUriL");
+ return MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, aUri, EFalse);
+ }
+
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+// ----------------------------------------------------------------------------
+// Get abstractalbum Id matching the given URI
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::GetAbstractAlbumIdMatchingUriL(
+ const TDesC& aUri)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAbstractAlbumIdMatchingUriL");
+ return MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXAbstractAlbum, aUri, EFalse);
+ }
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+
+// ----------------------------------------------------------------------------
+// Get all artists
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAllArtistsL(
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllArtistsL");
+ iDbArtist->GetAllCategoryItemsL(aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all albums
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAllAlbumsL(
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllAlbumsL");
+ iDbAlbum->GetAllCategoryItemsL(aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all albums for the given artist ID
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAlbumsMatchingArtistL(
+ TUint aArtistId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAlbumsMatchingArtistL");
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL( attributes );
+
+ TBool tryGetSongCount = EFalse;
+ TInt attrCount(aAttrs.Count());
+ TInt i = 0;
+ for (i = 0; i < attrCount; i++)
+ {
+ TInt contentId(aAttrs[i].ContentId());
+ TUint attributeId(aAttrs[i].AttributeId());
+
+ if (contentId == KMPXMediaIdGeneral && attributeId & EMPXMediaGeneralCount)
+ {
+ MPX_DEBUG1(" EMPXMediaGeneralCount");
+
+ attributes.Append(TMPXAttribute(KMPXMediaIdGeneral, attributeId & ~EMPXMediaGeneralCount));
+
+ tryGetSongCount = ETrue;
+ break;
+ }
+
+ attributes.Append(aAttrs[i]);
+ }
+
+ for (TInt j = i+1; j < attrCount; j++)
+ {
+ attributes.Append(aAttrs[j]);
+ }
+ iDbAlbum->GetSubCategoryItemsL(EMPXArtist, aArtistId, attributes.Array(), aMediaArray);
+ CleanupStack::PopAndDestroy(&attributes);
+
+ TInt pPath(0);
+ if (aMediaArray.Count())
+ {
+ CMPXMedia* pMedia = aMediaArray[0];
+ if (pMedia->IsSupported(KMPXMediaGeneralValue))
+ {
+ pPath = pMedia->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
+ MPX_ASSERT(pPath);
+ }
+ }
+
+ TInt albumCount(aMediaArray.Count());
+ if (albumCount)
+ {
+ if ( tryGetSongCount )
+ {
+ TInt startIndex = pPath ? 1 : 0;
+
+ for (TInt i = startIndex; i < albumCount; i++)
+ {
+ CMPXMedia* media = aMediaArray[i];
+ TUint32 albumId((media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)));
+
+ TInt songCount = iDbAlbum->GetSongsCountInAlbumMatchingArtistL(aArtistId, albumId);
+
+ media->SetTObjectValueL<TInt>(KMPXMediaGeneralCount, songCount );
+ MPX_DEBUG2(" SongCount[%d]", songCount );
+ }
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Get all genres
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAllGenresL(
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllGenresL");
+ iDbGenre->GetAllCategoryItemsL(aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all composers
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAllComposersL(
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllComposersL");
+ iDbComposer->GetAllCategoryItemsL(aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get the playlist ID of the playlist that matches the given URI
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::GetPlaylistIdMatchingUriL(
+ const TDesC& aUri)
+ {
+ MPX_FUNC("CMPXDbHandler::GetPlaylistIdMatchingUriL");
+ return iDbPlaylist->GetIdL(aUri);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::IsAutoPlaylistL
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbHandler::IsAutoPlaylistL(
+ TUint32 aPlaylistId)
+ {
+ MPX_FUNC("CMPXDbHandler::IsAutoPlaylistL");
+ return (iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) != EMPXNoAutoPlaylist);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all user playlist names
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAllPlaylistsL(
+ CMPXMediaArray* aMediaArray,
+ const TArray<TMPXAttribute>& aAttrs)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllPlaylistsL");
+ iDbPlaylist->GetAllPlaylistsL(aAttrs, *aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all system playlist names
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetAllSystemPlaylistNamesL(
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllSystemPlaylistNamesL()");
+ iAutoPlaylist->GetAllPlaylistsL(*aMediaArray);
+ }
+
+// ----------------------------------------------------------------------------
+// Get the name of the row matching the given ID
+// ----------------------------------------------------------------------------
+//
+HBufC* CMPXDbHandler::GetNameMatchingIdL(
+ const TUint32 aId) const
+ {
+ MPX_FUNC("CMPXDbHandler::GetNameMatchingIdL()");
+
+ HBufC* name(NULL);
+ TMPXGeneralCategory category(MPX_ITEM_CATEGORY(aId));
+ switch (category)
+ {
+ case EMPXCollection:
+ {
+ // song name
+ name = iDbMusic->GetNameL(aId);
+ break;
+ }
+ case EMPXPlaylist:
+ {
+ // playlist name
+ if (iAutoPlaylist->AutoPlaylistTypeL(aId) != EMPXNoAutoPlaylist)
+ {
+ name = iAutoPlaylist->AutoPlaylistNameL(aId).AllocL();
+ }
+ else
+ {
+ name = iDbPlaylist->GetNameL(aId);
+ }
+ break;
+ }
+ default:
+ {
+ // category name
+ name = DbCategoryL(category)->GetNameL(aId);
+ break;
+ }
+ }
+
+ return name;
+ }
+
+// ----------------------------------------------------------------------------
+// Get the URI of the row matching the given ID
+// ----------------------------------------------------------------------------
+//
+HBufC* CMPXDbHandler::GetUriMatchingIdL(
+ const TUint32 aId) const
+ {
+ MPX_FUNC("CMPXDbHandler::GetUriMatchingIdL");
+
+ HBufC* uri(NULL);
+ switch (MPX_ITEM_CATEGORY(aId))
+ {
+ case EMPXCollection:
+ {
+ // song URI
+ uri = iDbMusic->GetUriL(aId);
+ break;
+ }
+ case EMPXPlaylist:
+ {
+ // playlist URI
+ uri = iDbPlaylist->GetUriL(aId);
+ break;
+ }
+ default:
+ User::Leave(KErrNotSupported);
+ }
+
+ return uri;
+ }
+
+// ----------------------------------------------------------------------------
+// Get category
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetCategoryL(
+ const TUint32 aCategoryId,
+ TMPXGeneralCategory aCategory,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMedia* aMedia)
+ {
+ MPX_FUNC("CMPXDbHandler::GetCategoryL");
+
+ switch (aCategory)
+ {
+ case EMPXPlaylist:
+ {
+ if (iAutoPlaylist->AutoPlaylistTypeL(aCategoryId) != EMPXNoAutoPlaylist)
+ {
+ iAutoPlaylist->GetPlaylistL(aCategoryId, aAttrs, *aMedia);
+ }
+ else
+ {
+ iDbPlaylist->GetPlaylistL(aCategoryId, aAttrs, *aMedia);
+ }
+ break;
+ }
+ default:
+ {
+ DbCategoryL(aCategory)->GetCategoryItemL(aCategoryId, aAttrs, *aMedia);
+ break;
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Get the duration for all songs
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::GetAllSongsDurationL()
+ {
+ MPX_FUNC("CMPXDbHandler::GetAllSongsDurationL");
+ return iDbMusic->AllSongsDurationL();
+ }
+
+// ----------------------------------------------------------------------------
+// Get the duration for an artist
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::GetArtistDurationL(
+ TInt aArtistId)
+ {
+ MPX_FUNC("CMPXDbHandler::GetArtistDurationL");
+ return iDbMusic->ArtistDurationL(aArtistId);
+ }
+
+// ----------------------------------------------------------------------------
+// Get the duration for an album
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::GetAlbumDurationL(
+ TInt aAlbumId)
+ {
+ MPX_FUNC("CMPXDbHandler::GetAlbumDurationL");
+ return iDbMusic->AlbumDurationL(aAlbumId);
+ }
+
+// ----------------------------------------------------------------------------
+// Get the duration for an artist/album combination
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::GetArtistAlbumDurationL(
+ TInt aArtistId,
+ TInt aAlbumId)
+ {
+ MPX_FUNC("CMPXDbHandler::GetArtistAlbumDurationL");
+ return iDbMusic->ArtistAlbumDurationL(aArtistId, aAlbumId);
+ }
+
+// ----------------------------------------------------------------------------
+// Get the duration for a composer
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::GetComposerDurationL(
+ TInt aComposerId)
+ {
+ MPX_FUNC("CMPXDbHandler::GetComposerDurationL");
+ return iDbMusic->ComposerDurationL(aComposerId);
+ }
+
+// ----------------------------------------------------------------------------
+// Get the duration for a genre
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::GetGenreDurationL(
+ TInt aGenreId)
+ {
+ MPX_FUNC("CMPXDbHandler::GetGenreDurationL");
+ return iDbMusic->GenreDurationL(aGenreId);
+ }
+
+// ----------------------------------------------------------------------------
+// Get the duration for a user playlist
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::GetUserPlaylistDurationL(
+ TInt aPlaylistId)
+ {
+ MPX_FUNC("CMPXDbHandler::GetUserPlaylistDurationL");
+
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL(attributes);
+ attributes.AppendL(KMPXMediaGeneralId);
+ attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration));
+
+ CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
+ CleanupStack::PushL(mediaArray);
+
+ GetPlaylistSongsL(aPlaylistId, attributes.Array(), *mediaArray);
+
+ TInt duration(0);
+ TInt count(mediaArray->Count());
+ for (TInt index = 0; index < count; ++index)
+ {
+ CMPXMedia* media((*mediaArray)[index]);
+ if (media->IsSupported(KMPXMediaGeneralDuration))
+ {
+ duration += media->ValueTObjectL<TInt>(KMPXMediaGeneralDuration);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(mediaArray);
+ CleanupStack::PopAndDestroy(&attributes);
+
+ return duration;
+ }
+
+// ----------------------------------------------------------------------------
+// Get the duration for a playlist
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::GetPlaylistDurationL(
+ TInt aPlaylistId)
+ {
+ MPX_FUNC("CMPXDbHandler::GetPlaylistDurationL");
+
+ TInt duration(0);
+
+ if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist))
+ {
+ duration = iDbMusic->RecentlyPlayedDurationL();
+ }
+ else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist))
+ {
+ duration = iDbMusic->MostPlayedDurationL();
+ }
+ else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyAddedPlaylist))
+ {
+ duration = iDbMusic->RecentlyAddedDurationL();
+ }
+ else
+ {
+ duration = GetUserPlaylistDurationL(aPlaylistId);
+ }
+
+ return duration;
+ }
+
+// ----------------------------------------------------------------------------
+// Find the number of items of a specified type
+// ----------------------------------------------------------------------------
+//
+TInt CMPXDbHandler::NumberOfItemsL(
+ TMPXGeneralCategory aCategory)
+ {
+ MPX_FUNC("CMPXDbHandler::NumberOfItemsL");
+
+ TInt count(0);
+ switch(aCategory)
+ {
+ case EMPXSong:
+ {
+ count = iDbMusic->CountL();
+ break;
+ }
+ case EMPXPlaylist:
+ {
+ // return the total number of playlists, including the system ones
+ count = iDbPlaylist->CountL() + EMPXAutoPlaylistCount;
+ break;
+ }
+ default:
+ {
+ count = DbCategoryL(aCategory)->CountL();
+ break;
+ }
+ }
+
+ return count;
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::FindAllLC
+// ----------------------------------------------------------------------------
+//
+CMPXMedia* CMPXDbHandler::FindAllLC(
+ const CMPXMedia& aCriteria,
+ const TArray<TMPXAttribute>& aAttrs)
+ {
+ MPX_FUNC("CMPXDbHandler::FindAllLC");
+
+ // leave if the given media doesn't contain the following attributes
+ if (!aCriteria.IsSupported(KMPXMediaGeneralType) ||
+ !aCriteria.IsSupported(KMPXMediaGeneralCategory))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ RArray<TInt> supportedIds;
+ CleanupClosePushL(supportedIds);
+ supportedIds.AppendL(KMPXMediaIdContainer);
+ MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
+
+ CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
+ CleanupStack::PopAndDestroy(&supportedIds);
+ CleanupStack::PushL(entries);
+
+ CMPXMediaArray* array = CMPXMediaArray::NewL();
+ CleanupStack::PushL(array);
+
+ FindAllL(aCriteria, aAttrs, array);
+
+ entries->SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXGroup);
+ entries->SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory,
+ aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory));
+ entries->SetCObjectValueL(KMPXMediaArrayContents, array);
+ entries->SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
+
+ CleanupStack::PopAndDestroy(array);
+ return entries;
+ }
+
+// ----------------------------------------------------------------------------
+// Set the last refreshed time into the collection
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::SetLastRefreshedTimeL(
+ TTime aTime)
+ {
+ MPX_FUNC("CMPXDbHandler::SetLastRefreshedTimeL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, iDbAuxiliary->SetLastRefreshedTimeL(aTime));
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Get the last refreshed time from the collection
+// ----------------------------------------------------------------------------
+//
+TTime CMPXDbHandler::GetLastRefreshedTimeL()
+ {
+ MPX_FUNC("CMPXDbHandler::GetLastRefreshedTimeL");
+ return iDbAuxiliary->LastRefreshedTimeL();
+ }
+
+// ----------------------------------------------------------------------------
+// Set the db corrupted state for all drives
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::SetDBCorruptedL(
+ TBool aCorrupted)
+ {
+ MPX_FUNC("CMPXDbHandler::SetDBCorruptedL");
+
+ BeginTransactionL();
+ MPX_TRAPD(err, iDbAuxiliary->SetDBCorruptedL(aCorrupted));
+ EndTransactionL(err);
+ }
+
+// ----------------------------------------------------------------------------
+// Gets the db corrupted state for all drives
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbHandler::IsDBCorruptedL()
+ {
+ MPX_FUNC("CMPXDbHandler::IsDBCorruptedL");
+ return iDbAuxiliary->DBCorruptedL();
+ }
+
+// ----------------------------------------------------------------------------
+// Have the databases been created?
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbHandler::DatabaseCreated()
+ {
+ MPX_FUNC("CMPXDbHandler::DatabaseCreatedL");
+
+ TBool AuxilaryDbIsRefreshed(EFalse);
+ TRAP_IGNORE(AuxilaryDbIsRefreshed = iDbAuxiliary->IsRefreshedL());
+ // If none of the databases were available, ie out of disk we return EFalse
+ return iDbManager->IsInitialized() && AuxilaryDbIsRefreshed;
+ }
+
+// ----------------------------------------------------------------------------
+// Open a database
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::OpenDatabaseL(
+ TInt aDrive)
+ {
+ MPX_FUNC("CMPXDbHandler::OpenDatabaseL");
+ MPX_DEBUG2( "CMPXDbHandler::OpenDatabaseL: %i", aDrive);
+ iDbManager->OpenDatabaseL(aDrive);
+
+ // Verify the volume ID after a remount event
+ VerifyVolumeIdL( aDrive );
+ }
+
+// ----------------------------------------------------------------------------
+// Close a database
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::CloseDatabaseL(
+ TInt aDrive)
+ {
+ MPX_FUNC("CMPXDbHandler::CloseDatabaseL");
+ MPX_DEBUG2( "CMPXDbHandler::CloseDatabaseL drive: %i", aDrive );
+ iDbManager->CloseDatabaseL(aDrive);
+ }
+
+// ----------------------------------------------------------------------------
+// Re-create all databases
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::ReCreateDatabasesL()
+ {
+ MPX_FUNC("CMPXDbHandler::ReCreateDatabasesL");
+ iDbManager->RecreateAllDatabasesL();
+ }
+
+// ----------------------------------------------------------------------------
+// Set handler refresh status
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RefreshStartL()
+ {
+ MPX_FUNC("CMPXDbHandler::RefreshStartL");
+
+ iOutOfDisk = EFalse;
+ // Re-open databases
+ // This is needed for the case where we were OOD before, but user
+ // has cleared some space but now try to refresh
+ MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
+
+ if(err == KErrDiskFull)
+ {
+ iOutOfDisk = ETrue;
+ }
+
+ User::LeaveIfError( err );
+
+ if(!iOutOfDisk)
+ {
+ MPX_TRAP(err,CheckDiskSpaceOnDrivesL());
+
+ if(err == KErrDiskFull)
+ {
+ iOutOfDisk = ETrue;
+ }
+ }
+#ifdef __RAMDISK_PERF_ENABLE
+ iDbManager->CopyDBsToRamL();
+#endif //__RAMDISK_PERF_ENABLE
+
+ BeginTransactionL();
+ iRefresh = ETrue;
+ }
+
+// ----------------------------------------------------------------------------
+// Re-set handler refresh status
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::RefreshEndL()
+ {
+ MPX_FUNC("CMPXDbHandler::RefreshEndL");
+ if ( iRefresh )
+ {
+ iRefresh = EFalse;
+ EndTransactionL(KErrNone);
+ if (!iOutOfDisk)
+ {
+ // Write last refreshed time as current time
+ // This also sets corrupt = 0
+ TTime curTime;
+ curTime.HomeTime();
+ SetLastRefreshedTimeL(curTime);
+ }
+
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ //for AbstractAlbum garbage collection
+ TRAP_IGNORE( iDbAbstractAlbum->AbstractAlbumCleanUpL() );
+#endif
+
+#ifdef __RAMDISK_PERF_ENABLE
+ iDbManager->CopyDBsFromRamL();
+#endif //__RAMDISK_PERF_ENABLE
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Notification of Mtp status change
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::MtpStartL()
+ {
+ MPX_DEBUG1("-->CMPXDbHandler::MtpStartL");
+ if(!iMtpInUse)
+ {
+ iMtpInUse = ETrue;
+ iOpOnDbCount = 0;
+
+ #ifdef __RAMDISK_PERF_ENABLE
+ TRAPD(err, iDbManager->CopyDBsToRamL(iMtpInUse));
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CMPXDbHandler::MtpStartL error=%d", err);
+ }
+ #endif //__RAMDISK_PERF_ENABLE
+
+ iDbManager->BeginL();
+ }
+//create Thumbnail manager session for cleanup for abstractalbum when MTP end.
+//because when MTP end comes, in case of mode switching, we need to do it as fast as possible,
+//hence we don’t want the delay happens on that time.
+#ifdef RD_MPX_TNM_INTEGRATION
+ iDbAbstractAlbum->CreateTNMSessionL();
+#endif //RD_MPX_TNM_INTEGRATION
+ MPX_DEBUG1("<--CMPXDbHandler::MtpStartL");
+ }
+
+// ----------------------------------------------------------------------------
+// Notification of Mtp status change
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::MtpEndL()
+ {
+ MPX_DEBUG1("-->CMPXDbHandler::MtpEndL");
+ iMtpInUse = EFalse;
+ iOpOnDbCount = 0;
+ iDbManager->CommitL();
+ TInt err = KErrNone;
+
+
+#ifdef __RAMDISK_PERF_ENABLE
+ TRAP(err, iDbManager->CopyDBsFromRamL());
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CMPXDbHandler::MtpEndL error=%d", err);
+ }
+#endif //__RAMDISK_PERF_ENABLE
+
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ BeginTransactionL();
+ TRAP(err, iDbAbstractAlbum->RemoveAbstractAlbumsWithNoSongL());
+ if ( err != KErrNone )
+ {
+ MPX_DEBUG2("CMPXDbHandler::MtpEndL error happened when cleanup albstractalbum with no songs association[%d]", err);
+ }
+ EndTransactionL(err);
+#endif
+ MPX_DEBUG1("<--CMPXDbHandler::MtpEndL");
+ }
+
+// ----------------------------------------------------------------------------
+// Get all records count for music
+// ----------------------------------------------------------------------------
+//
+TUint CMPXDbHandler::GetMusicCountL(TInt aDrive)
+ {
+ MPX_FUNC("CMPXDbHandler::GetMusicCountL");
+ TUint total(0);
+
+ //music
+ total += iDbMusic->GetDriveTrackCountL(aDrive);
+
+ return total;
+ }
+
+// ----------------------------------------------------------------------------
+// Get all records count for playlists
+// ----------------------------------------------------------------------------
+//
+TUint CMPXDbHandler::GetPlaylistCountL(TInt aDrive)
+ {
+ MPX_FUNC("CMPXDbHandler::GetPlaylistCountL");
+ TUint total(0);
+
+ //playlist
+ total += iDbPlaylist->GetDrivePlaylistCountL(aDrive);
+
+ return total;
+ }
+
+// ----------------------------------------------------------------------------
+// Get all records count for music and playlists
+// ----------------------------------------------------------------------------
+//
+TUint CMPXDbHandler::GetTotalCountL(TInt aDrive)
+ {
+ MPX_FUNC("CMPXDbHandler::GetTotalCountL");
+ TUint total(0);
+
+ //music
+ total += iDbMusic->GetDriveTrackCountL(aDrive);
+ //playlist
+ total += iDbPlaylist->GetDrivePlaylistCountL(aDrive);
+
+ return total;
+ }
+
+// ----------------------------------------------------------------------------
+// Get all records count for music and playlists
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetMusicUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
+ CDesCArray& aUriArr, TInt& aLastID)
+ {
+ MPX_FUNC("CMPXDbHandler::GetMusicUriArrayL");
+
+ iDbMusic->GetMusicUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
+ }
+
+// ----------------------------------------------------------------------------
+// Get all records count for music and playlists
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetPlaylistUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
+ CDesCArray& aUriArr, TInt& aLastID)
+ {
+ MPX_FUNC("CMPXDbHandler::GetPlaylistUriArrayL");
+
+ iDbPlaylist->GetPlaylistUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
+ }
+
+// ----------------------------------------------------------------------------
+// Starts a transaction on all databases
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::BeginTransactionL()
+ {
+ MPX_FUNC("CMPXDbHandler::BeginTransactionL");
+
+#ifdef __RAMDISK_PERF_ENABLE
+ // EnsureRamSpaceL will copy dbs from ram if ram space is low or dbs exceeded
+ // max space.
+ TRAPD(err, iDbManager->EnsureRamSpaceL());
+ if (err)
+ {
+ //error but continue
+ }
+#endif //__RAMDISK_PERF_ENABLE
+
+ if(!iMtpInUse)
+ {
+ iDbManager->BeginL();
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Ends a transaction on all databases
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::EndTransactionL(
+ TInt aError)
+ {
+ MPX_FUNC("CMPXDbHandler::EndTransactionL");
+
+ if(iMtpInUse)
+ {
+ if (aError)
+ {
+ iOpOnDbCount = 0;
+ iDbManager->RollbackL();
+ User::Leave(aError);
+ }
+
+ if(iOpOnDbCount >= KMaxOpInTransaction)
+ {
+ MPX_DEBUG2("CMPXDbHandler::EndTransactionL - %d>KMaxOpInTransaction Commiting",iOpOnDbCount);
+ iOpOnDbCount = 0;
+ iDbManager->CommitL();
+ iDbManager->BeginL();
+ }
+ }
+ else
+ {
+ if (aError)
+ {
+ MPX_DEBUG2("CMPXDbHandler::EndTransactionL - Rollback [%d]", aError);
+
+ iDbManager->RollbackL();
+
+ // KSqlDbCorrupted indicates DB corrupted, need to recreate.
+ if ( aError != KSqlDbCorrupted )
+ {
+ User::Leave(aError);
+ }
+ }
+ else
+ {
+ iDbManager->CommitL();
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Checks if the database is currently in a transaction
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbHandler::InTransaction()
+ {
+ MPX_FUNC("CMPXDbHandler::InTransaction");
+ return iDbManager->InTransaction();
+ }
+
+// ----------------------------------------------------------------------------
+// Notifies the handler that the collection will be closed.
+// It is called before closing the collection.
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::PreCloseCollectionL()
+ {
+ MPX_FUNC("CMPXDbHandler::PreCloseCollectionL");
+ // Complete pending transaction and set the latest refresh time
+ // before closing the databases if collection close event occurs
+ // before the end of the refresh operation
+ if(iRefresh)
+ {
+ EndTransactionL(KErrNone);
+ if (!iOutOfDisk)
+ {
+ // Write last refreshed time as current time
+ // This also sets corrupt = 0
+ TTime curTime;
+ curTime.HomeTime();
+ SetLastRefreshedTimeL(curTime);
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Add song to collection
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::DoAddSongL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray* aMessageArray)
+ {
+ MPX_FUNC("CMPXDbHandler::DoAddSongL");
+
+ if (!aMedia.IsSupported(KMPXMediaGeneralUri))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // add the song to the Music table
+ TDriveUnit drive(aMedia.ValueText(KMPXMediaGeneralUri));
+ TUint32 songId(iDbMusic->AddSongL(aMedia, drive,
+ iRefresh?NULL:aMessageArray));
+
+ // update the playlist tables
+ // make sure the song db flags are reset and not just updated
+ iDbPlaylist->UpdateSongL(aMedia, ETrue);
+
+ if(iMtpInUse)
+ {
+ ++iOpOnDbCount;
+ }
+
+ return songId;
+ }
+
+// ----------------------------------------------------------------------------
+// Add playlist to collection
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::DoAddPlaylistL(
+ const CMPXMedia& aMedia)
+ {
+ MPX_FUNC("CMPXDbHandler::DoAddPlaylistL");
+
+ CMPXMedia* media = CMPXMedia::NewL(aMedia);
+ CleanupStack::PushL(media);
+
+ const TDesC& playlistUri = media->ValueText(KMPXMediaGeneralUri);
+
+ //
+ // client has asked to create a virtual playlist if file name is not specified
+ // in the URI. In this case, generate URI for virtual playlist specified as
+ // follows:
+ // <dir path>\timestamp.vir
+ //
+ TParsePtrC parser(playlistUri);
+
+ if (!parser.NameOrExtPresent() ||
+ parser.IsNameWild() ||
+ parser.IsExtWild())
+ {
+ HBufC* newUri = HBufC::NewLC(parser.DriveAndPath().Length() + KMCMaxTextLen +
+ KMPXVirtualPlaylistExt().Length());
+
+ TPtr ptr = newUri->Des();
+ ptr.Append(parser.DriveAndPath());
+ TTime time;
+ time.HomeTime();
+ ptr.AppendNum(time.Int64());
+ ptr.Append(KMPXVirtualPlaylistExt);
+
+ // overwrite the old uri with the new one with full path and playlist
+ // playlist filename
+ media->SetTextValueL(KMPXMediaGeneralUri, *newUri);
+
+ CleanupStack::PopAndDestroy(newUri);
+
+ // set DbFlags to indicate that this is a virtual playlist
+ media->SetTObjectValueL<TUint>(KMPXMediaGeneralFlags,
+ KMPXMediaGeneralFlagsSetOrUnsetBit | KMPXMediaGeneralFlagsIsVirtual);
+ }
+
+ // complete the song attributes from the music table
+ UpdatePlaylistSongInfoL(*media);
+
+ // add playlist to the database
+ TUint32 playlistId = iDbPlaylist->AddPlaylistL(*media);
+
+ CleanupStack::PopAndDestroy(media);
+ return playlistId;
+ }
+
+// ----------------------------------------------------------------------------
+// Add song to playlist
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::DoAddSongToPlaylistL(
+ const CMPXMedia& aMedia)
+ {
+ MPX_FUNC("CMPXDbHandler::DoAddSongToPlaylistL");
+
+ CMPXMedia* media = CMPXMedia::NewL(aMedia);
+ CleanupStack::PushL(media);
+
+ // complete the song attributes from the music table
+ UpdatePlaylistSongInfoL(*media);
+
+ // add the songs to the playlist
+ TUint32 playlistId((media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2);
+
+ CMPXMediaArray* ary( aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents) );
+ User::LeaveIfNull( ary );
+ iDbPlaylist->AddSongsL(playlistId,*ary);
+
+ CleanupStack::PopAndDestroy(media);
+ return playlistId;
+ }
+
+// ----------------------------------------------------------------------------
+// Update a song in the collection
+// ----------------------------------------------------------------------------
+//
+CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::DoUpdateSongL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::DoUpdateSongL");
+
+ CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
+
+ TUint32 songId(0);
+
+ if (aMedia.IsSupported(KMPXMediaGeneralId))
+ {
+ songId = (aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
+ }
+ if (aMedia.IsSupported(KMPXMediaGeneralUri))
+ {
+ const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri);
+ songId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, uri, EFalse);
+ }
+ if (!songId)
+ {
+ User::Leave(KErrNotSupported);
+ }
+
+ // Update the Music table
+ TRAPD(err, visibleChange = iDbMusic->UpdateSongL(songId, aMedia, aItemChangedMessages));
+
+ // do not leave if song is not found in Music table
+ // leave for other errors such as disk full
+ if(err != KErrNone && err != KErrNotFound)
+ {
+ User::Leave(err);
+ }
+
+ // Update the Playlist table
+ TBool visible = EFalse;
+
+ TRAP( err, visible = iDbPlaylist->UpdateSongL(aMedia, EFalse, &aItemChangedMessages));
+
+ // do not leave if song is not found in Playlist table
+ // leave for other errors such as disk full
+ if(err != KErrNone && err != KErrNotFound)
+ {
+ User::Leave(err);
+ }
+
+ // make it visible if either table is updated
+ if (visible)
+ {
+ visibleChange = CMPXDbActiveTask::EAllVisible;
+ }
+ if ( aMedia.ValueTObjectL<TInt>( KMPXMediaMusicAlbumArtChanged )== 1 )
+ {
+ ( const_cast<CMPXMedia*>( &aMedia )
+ )->SetTObjectValueL<TInt>( KMPXMediaMusicAlbumArtChanged, 0 );
+ }
+
+ return visibleChange;
+ }
+
+// ----------------------------------------------------------------------------
+// Update a playlist in the collection
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoUpdatePlaylistL(
+ const CMPXMedia& aMedia,
+ CMPXMessageArray& aMessageArray)
+ {
+ MPX_FUNC("CMPXDbHandler::DoUpdatePlaylistL");
+
+ TUint32 playlistId(0);
+ TInt drive(0);
+
+ CMPXMedia* media = CMPXMedia::NewL(aMedia);
+ CleanupStack::PushL(media);
+
+
+ ProcessPlaylistMediaL(*media, playlistId, drive);
+
+ CMPXMessage* m1 = CMPXMessage::NewL();
+ CleanupStack::PushL(m1);
+ CMPXMessage* m2 = CMPXMessage::NewL();
+ CleanupStack::PushL(m2);
+
+ // send 2 messages to notify the playlist change & to refresh the display (update playlist name)
+ MPXDbCommonUtil::FillItemChangedMessageL(*m1, playlistId, EMPXItemModified,
+ EMPXPlaylist, KDBPluginUid);
+
+ MPXDbCommonUtil::FillItemChangedMessageL(*m2, EBrowsePlaylist, EMPXItemModified,
+ EMPXPlaylist, KDBPluginUid);
+
+ iDbPlaylist->UpdatePlaylistL(*media, *m1, drive);
+
+ aMessageArray.AppendL(*m1);
+ aMessageArray.AppendL(*m2);
+
+
+ CleanupStack::PopAndDestroy(m2);
+ CleanupStack::PopAndDestroy(m1);
+ CleanupStack::PopAndDestroy(media);
+ }
+
+// ----------------------------------------------------------------------------
+// Update a playlist in the collection
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoUpdatePlaylistSongsL(
+ const CMPXMedia& aMedia,
+ CMPXMessage& aMessage)
+ {
+ MPX_FUNC("CMPXDbHandler::DoUpdatePlaylistSongsL");
+
+ CMPXMedia* media = CMPXMedia::NewL(aMedia);
+ CleanupStack::PushL(media);
+
+ TUint32 playlistId(0);
+ TInt drive(0);
+
+ // get the playlist ID and drive ID
+ ProcessPlaylistMediaL(*media, playlistId, drive);
+ MPXDbCommonUtil::FillItemChangedMessageL(aMessage, playlistId, EMPXItemModified,
+ EMPXPlaylist, KDBPluginUid);
+
+ // complete the song attributes from the Music table
+ UpdatePlaylistSongInfoL(*media);
+
+ // delete existing songs for the playlist first
+ iDbPlaylist->Songs().DeleteSongsL(playlistId, drive);
+
+ // add new songs to the playlist
+ CMPXMediaArray* ary( media->Value<CMPXMediaArray>(KMPXMediaArrayContents ) );
+ User::LeaveIfNull( ary );
+ iDbPlaylist->AddSongsL(playlistId, *ary);
+
+ CleanupStack::PopAndDestroy(media);
+ }
+
+// ----------------------------------------------------------------------------
+// Reorder a song in a playlist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoReorderPlaylistL(
+ const TMPXItemId& aPlaylistId,
+ const TMPXItemId& aSongId,
+ TUint aOriginalOrdinal,
+ TUint aNewOrdinal,
+ CMPXMessage& aMessage)
+ {
+ MPX_DEBUG1("-->CMPXDbHandler::DoReorderPlaylistL()");
+
+ if (aOriginalOrdinal != aNewOrdinal)
+ {
+ iDbPlaylist->Songs().ReorderSongL(aPlaylistId, aSongId, aOriginalOrdinal, aNewOrdinal);
+
+ MPXDbCommonUtil::FillItemChangedMessageL(aMessage, aPlaylistId.iId2, EMPXItemModified,
+ EMPXPlaylist, KDBPluginUid);
+ }
+
+ MPX_DEBUG1("<--CMPXDbHandler::DoReorderPlaylistL()");
+ }
+
+// ----------------------------------------------------------------------------
+// Delete a song from collection
+// The function notifies collection model to perform deletion
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoRemoveSongL(
+ TUint32 aSongId,
+ CDesCArray& aUriArray,
+ CMPXMessageArray& aItemChangedMessages,
+ TBool aDeleteRecord)
+ {
+ MPX_FUNC("CMPXDbHandler::DoRemoveSongL");
+
+ // Get the song drive
+ TUint32 artistID(0);
+ TUint32 albumID(0);
+ TUint32 genreID(0);
+ TUint32 composerID(0);
+ HBufC* art(NULL);
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ TUint32 abstractAlbumID(0);
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+ TInt drive(0);
+
+// Get information from the Music table first
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ HBufC* uri = iDbMusic->GetSongInfoL(aSongId, artistID, albumID, genreID, composerID, abstractAlbumID, drive, art);
+#else
+ HBufC* uri = iDbMusic->GetSongInfoL(aSongId, artistID, albumID, genreID, composerID, drive, art);
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+
+ CleanupStack::PushL(art);
+ // add the URI to the return array
+ CleanupStack::PushL(uri);
+ aUriArray.AppendL(*uri);
+ CleanupStack::PopAndDestroy(uri);
+
+ // Update the category records
+ TBool categoryExist( EFalse );
+ iDbArtist->DecrementSongsForCategoryL(artistID, drive, &aItemChangedMessages, categoryExist);
+ iDbAlbum->DecrementSongsForCategoryL(albumID, drive, &aItemChangedMessages, categoryExist, artistID, *art);
+ iDbGenre->DecrementSongsForCategoryL(genreID, drive, &aItemChangedMessages, categoryExist);
+ iDbComposer->DecrementSongsForCategoryL(composerID, drive, &aItemChangedMessages, categoryExist);
+ CleanupStack::PopAndDestroy(art);
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ if (abstractAlbumID)
+ {
+ iDbAbstractAlbum->DecrementSongsForCategoryL(abstractAlbumID, drive, &aItemChangedMessages, categoryExist, iMtpInUse);
+ }
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+ // Update the music table
+ TBool deleteRecord(ETrue);
+
+#if defined (__MTP_PROTOCOL_SUPPORT)
+ // Mark the song record as deleted if the following is true; otherwise, delete the
+ // song record.
+ //
+ // A client other than MTP has initiated this song deletion (aDeleteRecord is EFalse)
+ // and MTP has turned on its cenrep key to save deleted records and current number of
+ // saved deleted records has not exceeded its maximum, KMCMaxSavedDeletedRecords.
+ //
+ // Songs are marked as deleted in order to support auto-sync. MTP will delete these
+ // marked records at the end of each session via CleanupDeletedRecordsL.
+ //
+ // For performance consideration, if the number of saved records exceeds its maximum,
+ // song record will be deleted.
+ if (!aDeleteRecord && SaveDeletedSongs())
+ {
+ TUint32 savedDeletedRecordCount(iDbAuxiliary->SaveDeletedRecordCountL());
+ MPX_DEBUG2("Current number of saved deleted record count is %d", savedDeletedRecordCount);
+
+ if (savedDeletedRecordCount < KMCMaxSavedDeletedRecords)
+ {
+ deleteRecord = EFalse;
+ TUint32 savedDeletedDriveRecordCount(iDbAuxiliary->SaveDeletedRecordCountL(drive));
+ iDbAuxiliary->SetSaveDeletedRecordCountL(drive,++savedDeletedDriveRecordCount);
+ }
+ }
+#endif
+
+ // delete the song from the Music table
+ iDbMusic->DeleteSongL(aSongId, drive, deleteRecord);
+
+ // add the item changed message
+ MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aSongId, EMPXItemDeleted,
+ EMPXSong, KDBPluginUid);
+
+
+ if(iMtpInUse)
+ {
+ ++iOpOnDbCount;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Delete a song from playlist tables
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoRemoveSongFromPlaylistL(TUint32 aSongId,CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::DoRemoveSongFromPlaylistL");
+ // delete song from the playlist tables on all drives
+ iDbPlaylist->DeleteSongL(aSongId, aItemChangedMessages);
+ }
+
+// ----------------------------------------------------------------------------
+// Removes a category of songs from the music collection,
+// and its corresponding category in the lookup table
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoRemoveSongsMatchingCategoryL(
+ TMPXGeneralCategory aCategory,
+ TUint32 aCategoryId,
+ CDesCArray& aUriArray,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::DoRemoveSongsMatchingCategoryL");
+
+ // get the songs for the specified category
+ CMPXMediaArray* songs = CMPXMediaArray::NewL();
+ CleanupStack::PushL(songs);
+
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL(attributes);
+ attributes.AppendL(KMPXMediaGeneralId);
+
+ switch (aCategory)
+ {
+ case EMPXArtist:
+ {
+ iDbMusic->GetSongsForArtistL(aCategoryId, attributes.Array(), *songs);
+ break;
+ }
+ case EMPXAlbum:
+ {
+ iDbMusic->GetSongsForAlbumL(aCategoryId, attributes.Array(), *songs);
+ break;
+ }
+ case EMPXGenre:
+ {
+ iDbMusic->GetSongsForGenreL(aCategoryId, attributes.Array(), *songs);
+ break;
+ }
+ case EMPXComposer:
+ {
+ iDbMusic->GetSongsForComposerL(aCategoryId, attributes.Array(), *songs);
+ break;
+ }
+ default:
+ User::Leave(KErrNotSupported);
+ }
+
+ CleanupStack::PopAndDestroy(&attributes);
+
+ // iterate the songs and remove them one by one
+ // so records in the category tables can also be updated
+ TInt count(songs->Count());
+ for (TInt index = 0; index < count; ++index)
+ {
+ CMPXMedia* song = (*songs)[index];
+ if (song->IsSupported(KMPXMediaGeneralId))
+ {
+ DoRemoveSongL((song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2,
+ aUriArray, aItemChangedMessages, EFalse);
+ DoRemoveSongFromPlaylistL((song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2,aItemChangedMessages);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(songs);
+ }
+
+// ----------------------------------------------------------------------------------------------------------
+// Delete songs for the specified artist and album from collection
+// ----------------------------------------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoRemoveSongsMatchingArtistAndAlbumL(
+ TUint32 aArtistId,
+ TUint32 aAlbumId,
+ CDesCArray& aUriArray,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL");
+
+ // get the songs for the specified artist and album
+ CMPXMediaArray* songs = CMPXMediaArray::NewL();
+ CleanupStack::PushL(songs);
+
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL (attributes);
+ attributes.AppendL(KMPXMediaGeneralId);
+
+ iDbMusic->GetSongsForArtistAndAlbumL(aArtistId, aAlbumId, attributes.Array(), *songs);
+ CleanupStack::PopAndDestroy(&attributes);
+
+ // iterate the songs and remove them one by one
+ // so records in the category tables can also be updated
+ TInt count(songs->Count());
+ for (TInt index = 0; index < count; ++index)
+ {
+ CMPXMedia* song = (*songs)[index];
+ if (song->IsSupported(KMPXMediaGeneralId))
+ {
+ DoRemoveSongL( song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),
+ aUriArray, aItemChangedMessages, EFalse);
+ DoRemoveSongFromPlaylistL(song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),aItemChangedMessages);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(songs);
+ }
+
+// ----------------------------------------------------------------------------
+// Remove all playlists from collection
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoRemoveAllPlaylistsL()
+ {
+ MPX_FUNC("CMPXDbHandler::DoRemoveAllPlaylistsL");
+ iDbPlaylist->DeleteAllPlaylistsL();
+ }
+
+// ----------------------------------------------------------------------------
+// Remove specified playlist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoRemovePlaylistL(
+ TUint32 aPlaylistId,
+ CDesCArray& aUriArray,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::DoRemovePlaylistL");
+
+ HBufC* uri(iDbPlaylist->DeletePlaylistL(aPlaylistId));
+ if (uri)
+ {
+ CleanupStack::PushL(uri);
+ aUriArray.AppendL(*uri);
+ CleanupStack::PopAndDestroy(uri);
+ }
+
+ MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aPlaylistId, EMPXItemDeleted,
+ EMPXPlaylist, KDBPluginUid);
+ }
+
+// ----------------------------------------------------------------------------
+// Remove song from playlist songs table
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoRemoveSongFromPlaylistL(
+ TUint32 aPlaylistId,
+ const TMPXItemId& aSongId,
+ TInt aOrdinal,
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::DoRemoveSongFromPlaylistL");
+ MPX_DEBUG5("CMPXDbHandler::DoRemoveSongFromPlaylistL(playlist 0x%x, songId [0x%x,0x%x], ordinal %d)",
+ aPlaylistId, aSongId.iId1, aSongId.iId2, aOrdinal);
+
+ // delete the song
+ iDbPlaylist->DeleteSongL(aPlaylistId, aSongId.iId2, aOrdinal);
+
+ // Send a playlist modified message
+ MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aPlaylistId, EMPXItemModified,
+ EMPXPlaylist, KDBPluginUid);
+
+ // Send a message on the song in the playlist that is deleted
+ MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aSongId, EMPXItemDeleted,
+ EMPXSong, KDBPluginUid);
+ }
+
+
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::DoCleanupDeletedRecordsL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DoCleanupDeletedRecordsL()
+ {
+ MPX_FUNC("CMPXDbHandler::DoCleanupDeletedRecordsL");
+
+ // delete all marked records from the Music table
+ iDbMusic->CleanupL();
+
+ // reset the count in the Auxiliary table
+ iDbAuxiliary->SetSaveDeletedRecordCountL(KDbManagerAllDrives,0);
+ }
+
+// ----------------------------------------------------------------------------
+// FindAllL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::FindAllL(
+ const CMPXMedia& aCriteria,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray* aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::FindAllL");
+
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL(attributes);
+ MPXUser::MergeAttributeL(aAttrs, attributes);
+
+ TMPXGeneralCategory category = aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
+ switch (category)
+ {
+ case EMPXPlaylist:
+ {
+ TUint32 playlistId(0);
+ if (aCriteria.IsSupported(KMPXMediaGeneralId))
+ {
+ playlistId = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
+ }
+
+ if (iAutoPlaylist->AutoPlaylistTypeL(playlistId) != EMPXNoAutoPlaylist)
+ {
+ CMPXMedia* media = CMPXMedia::NewL();
+ CleanupStack::PushL(media);
+
+ iAutoPlaylist->GetPlaylistL(playlistId, aAttrs, *media);
+
+ aMediaArray->AppendL(*media);
+ CleanupStack::PopAndDestroy(media);
+ }
+ else
+ {
+ iDbPlaylist->FindAllL(aCriteria, attributes.Array(), *aMediaArray);
+ }
+
+ break;
+ }
+ case EMPXSong:
+ {
+ FindSongL(aCriteria, attributes.Array(), *aMediaArray);
+ break;
+ }
+ default:
+ {
+ DbCategoryL(category)->FindAllL(aCriteria, attributes.Array(), *aMediaArray);
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy(&attributes);
+ }
+
+// ----------------------------------------------------------------------------
+// Get song(s) from the music table that match the given criteria
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::FindSongL(
+ const CMPXMedia& aCriteria,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbCollection::FindSongL");
+
+ TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
+
+ TUint32 id(0);
+ if (aCriteria.IsSupported(KMPXMediaGeneralId))
+ {
+ id = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
+ }
+
+ TUint32 containerId(0);
+ if (aCriteria.IsSupported(KMPXMediaGeneralContainerId))
+ {
+ containerId = aCriteria.ValueTObjectL<TUint32>(KMPXMediaGeneralContainerId);
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Find songs in the specified playlist
+ //////////////////////////////////////////////////////////////////////
+ TMPXGeneralCategory cat(MPX_ITEM_CATEGORY(id));
+
+ if (type == EMPXGroup &&
+ (cat == EMPXPlaylist ||
+ MPX_ITEM_CATEGORY(containerId) == EMPXPlaylist))
+ {
+ TUint32 playlistId = (cat == EMPXPlaylist) ?
+ id : (containerId & KMCCategoryMask);
+
+ GetPlaylistSongsL(playlistId, aAttrs, aMediaArray);
+ }
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ else if (type == EMPXGroup &&
+ (cat == EMPXAbstractAlbum ||
+ MPX_ITEM_CATEGORY(containerId) == EMPXAbstractAlbum))
+ {
+ TUint32 abstractAlbumId = (cat == EMPXAbstractAlbum) ?
+ id : (containerId & KMCCategoryMask);
+ TInt attrCount(aAttrs.Count());
+ if ( attrCount > 1 || (attrCount == 1 && !(aAttrs[0] == KMPXMediaGeneralId)) )
+ {
+ MPX_TRAPD(err, iDbMusic->GetAllSongsForAbstractAlbumL( abstractAlbumId, aAttrs, aMediaArray));
+ if (err == KErrNotFound)
+ {
+ //
+ // Leave with KErrNotFound
+ User::Leave(KErrNotFound);
+ }
+ else
+ {
+ // Leave if error
+ User::LeaveIfError(err);
+ }
+ }
+ }
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+ //////////////////////////////////////////////////////////////////////
+ // Find a particular song in the specified playlist. This fills the
+ // song with info from Playlist table first then overwrites it with
+ // info from Songs table if Songs table where this song is located
+ // is present in order to support the display of song titles in a
+ // playlist when memory card is removed if the playlist refers to
+ // songs on the memory card. Caller of this scenario is OpenL/MediaL.
+ // When user attempts to play a track in an auto-playlist, we will
+ // find the song from Songs table directly since auto-playlists are
+ // not stored in the Playlist table. Auto-playlists are query-based,
+ // therefore, when memory card is removed, songs on the memory card
+ // will not be shown in the auto-playlist; hence they do not exhibit
+ // the same challenge as user created playlists.
+ //////////////////////////////////////////////////////////////////////
+ else if (type == EMPXItem &&
+ cat == EMPXCollection &&
+ MPX_ITEM_CATEGORY(containerId) == EMPXPlaylist)
+ {
+ if (iAutoPlaylist->AutoPlaylistTypeL(containerId) != EMPXNoAutoPlaylist)
+ {
+ // auto playlist song, get the song details from the music table
+ iDbMusic->FindSongsL(id, 0, type, aCriteria, aAttrs, aMediaArray);
+ }
+ else
+ {
+ GetPlaylistSongL(id, containerId, aAttrs, aMediaArray);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // Find all songs, all songs in a particular album and/or artist, or
+ // a particular song
+ //////////////////////////////////////////////////////////////////////
+ else
+ {
+ iDbMusic->FindSongsL(id, containerId, type, aCriteria, aAttrs, aMediaArray);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Get song(s) in the specified playlist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::GetPlaylistSongsL(
+ TUint32 aPlaylistId,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::GetPlaylistSongsL");
+ MPX_DEBUG2("CMPXDbHandler::GetPlaylistSongsL(0x%x)", aPlaylistId);
+
+ // check the auto playlists first
+ if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist))
+ {
+ iDbMusic->GetRecentlyPlayedSongsL(aAttrs, aMediaArray);
+ }
+ else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist))
+ {
+ iDbMusic->GetMostPlayedSongsL(aAttrs, aMediaArray);
+ }
+ else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyAddedPlaylist))
+ {
+ iDbMusic->GetRecentlyAddedSongsL(aAttrs, aMediaArray);
+ }
+ else
+ {
+ TInt attrCount(aAttrs.Count());
+ if ( attrCount > 1 || (attrCount == 1 && !(aAttrs[0] == KMPXMediaGeneralId)) )
+ {
+ TInt plDrive(iDbPlaylist->GetDriveIdL(aPlaylistId));
+ MPX_TRAPD(err, iDbMusic->GetAllSongsL(plDrive, aPlaylistId, aAttrs, aMediaArray));
+
+ // song not found in Music table
+ if (err == KErrNotFound)
+ {
+ //
+ // Leave with KErrNotFound if one of the following is true:
+ // 1) the requested song is in an auto playlist. Since auto-playlist isn't
+ // stored in playlist tables, we won't be able to retrieve info elsewhere
+ // 2) the requested song is in a user playlist but we cannot find the song
+ // info from playlist tables either
+ //
+ if (EMPXNoAutoPlaylist != iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) ||
+ !iDbPlaylist->Songs().GetSongsL(aPlaylistId, aAttrs, aMediaArray))
+ {
+ User::Leave(KErrNotFound);
+ }
+ }
+ else
+ {
+ // ignore the error if KErrNotFound
+ User::LeaveIfError(err);
+ }
+ }
+ else
+ {
+ // get ids of the songs in the playlist
+ iDbPlaylist->Songs().GetSongsL(aPlaylistId, aMediaArray);
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Find all albums or the albums for a specified artist
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::FindAlbumL(
+ const CMPXMedia& aCriteria,
+ const TArray<TMPXAttribute>& aAttrs,
+ CMPXMediaArray& aMediaArray)
+ {
+ MPX_FUNC("CMPXDbHandler::FindAlbumL");
+
+ TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
+
+ TUint32 id(0);
+ if (aCriteria.IsSupported(KMPXMediaGeneralId))
+ {
+ id = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
+ }
+
+ if ((type == EMPXGroup) && (MPX_ITEM_CATEGORY(id) == EMPXArtist))
+ {
+ // get all the albums for the artist
+ GetAlbumsMatchingArtistL(id, aAttrs, aMediaArray);
+ }
+ else
+ {
+ // look up all albums from album table
+ iDbAlbum->FindAllL(aCriteria, aAttrs, aMediaArray);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Extracts the playlist ID and drive ID from a playlist media instance
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::ProcessPlaylistMediaL(
+ CMPXMedia& aMedia,
+ TUint32& aPlaylistId,
+ TInt& aPlaylistDriveId)
+ {
+ MPX_FUNC("CMPXDbHandler::ProcessPlaylistMediaL");
+
+ if (aMedia.IsSupported(KMPXMediaGeneralId))
+ {
+ aPlaylistId = aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
+
+ if (aMedia.IsSupported(KMPXMediaGeneralUri))
+ {
+ // find drive id of the playlist
+ aPlaylistDriveId = TDriveUnit(aMedia.ValueText(KMPXMediaGeneralUri));
+ }
+ else
+ {
+ // Find drive Id(s) of corresponding Playlist Id
+ aPlaylistDriveId = iDbPlaylist->GetDriveIdL(aPlaylistId);
+ }
+ }
+ else if (aMedia.IsSupported(KMPXMediaGeneralUri))
+ {
+ const TDesC& playlistUri = aMedia.ValueText(KMPXMediaGeneralUri);
+ // find drive id of the playlist
+ aPlaylistDriveId = TDriveUnit(playlistUri);
+
+ // aMedia does not have an ID, make sure the add it
+ aPlaylistId = GetPlaylistIdMatchingUriL(playlistUri);
+ aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPlaylistId);
+ }
+ else
+ {
+ User::Leave(KErrArgument);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Makes sure that all songs in the specified playlist have the ID, title and URI attributes
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::UpdatePlaylistSongInfoL(
+ CMPXMedia& aMedia)
+ {
+ MPX_FUNC("CMPXDbHandler::UpdatePlaylistSongInfoL");
+
+ CMPXMediaArray* mediaArray = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
+ User::LeaveIfNull(mediaArray);
+
+ // make sure each song has Id, Uri, and Title before they can be added to playlist
+ TInt count(mediaArray->Count());
+ for (TInt i = 0; i < count; ++i)
+ {
+ CMPXMedia* element = mediaArray->AtL(i);
+
+ // copy each song to deal w/ global heap issues
+ CMPXMedia* entry = CMPXMedia::NewL(*element);
+ CleanupStack::PushL(entry);
+
+ // song has everything, go to next song
+ if (entry->IsSupported(KMPXMediaGeneralUri) &&
+ entry->IsSupported(KMPXMediaGeneralId) &&
+ entry->IsSupported(KMPXMediaGeneralTitle))
+ {
+ // pop entry to maintain CleanupStack
+ CleanupStack::PopAndDestroy(entry);
+ continue;
+ }
+
+ // songs must contain (at minimum) an Uri or an Id
+ if (!entry->IsSupported(KMPXMediaGeneralUri) &&
+ !entry->IsSupported(KMPXMediaGeneralId))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // get Id
+ if (!entry->IsSupported(KMPXMediaGeneralId))
+ {
+ // fill in the ID if not present
+ TParsePtrC parser(entry->ValueText(KMPXMediaGeneralUri));
+ entry->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,
+ MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, parser.FullName(), EFalse));
+ }
+
+ CMPXMedia* song(NULL);
+
+ // update songs info
+ TInt error(iDbMusic->GetSongL(*entry, song));
+ TBool result (ETrue);
+
+ // error can only be KErrNone or KErrNotFound
+ // from CMPXDbMusic::GetSongL
+ // if not found in Music, get info from PlaylistSongs (PlaylistSongs & PlaylistSongInfo) DB
+ if (error == KErrNotFound)
+ {
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL(attributes);
+ attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral,
+ EMPXMediaGeneralId | EMPXMediaGeneralTitle | EMPXMediaGeneralUri | EMPXMediaGeneralFlags));
+
+ // this song doesn't exist in Music table. This song is either a broken link or
+ // is of an unsupported song type that exists in the file system. Broken links
+ // have already been marked as such during playlist import.
+ result = iDbPlaylist->Songs().GetSongL(entry->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId), attributes.Array(), song);
+ if (!result)
+ {
+ // song is a broken link
+ //TUint flags = KMPXMediaGeneralFlagsSetOrUnsetBit;
+ //flags |= KMPXMediaGeneralFlagsIsInvalid; // set flag
+ //t->SetTObjectValueL<TUint>( KMPXMediaGeneralFlags, flags );
+
+ if (entry->IsSupported(KMPXMediaGeneralUri))
+ {
+ // no valid Id but has Uri, just verify Title is present
+ // this is the case if the song is a broken link or podcast
+ if (!entry->IsSupported(KMPXMediaGeneralTitle))
+ {
+ // does not have Title, make up the Title from file name
+ TParsePtrC parser(entry->ValueText(KMPXMediaGeneralUri));
+ entry->SetTextValueL(KMPXMediaGeneralTitle, parser.Name());
+ }
+ }
+ else
+ {
+ // no valid Id & no Uri, bad argument
+ User::Leave(KErrArgument);
+ }
+ }
+ CleanupStack::PopAndDestroy(&attributes);
+ }
+
+ // update attributes
+ CleanupStack::PushL(song);
+
+ // song not found in Music or Playlist DB, update entry
+ if(error == KErrNotFound && !result)
+ {
+ mediaArray->InsertL(*entry,i);
+ }
+ else // found in DB, replace entry
+ {
+ mediaArray->InsertL(*song,i);
+ }
+
+ // replace element in the array
+ CleanupStack::PopAndDestroy(song);
+ CleanupStack::PopAndDestroy(entry);
+ mediaArray->Remove(i+1);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::ProcessMusicFoldersL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::ProcessMusicFoldersL(
+ const CDesCArray& aFolders)
+ {
+ MPX_FUNC("CMPXDbHandler::ProcessMusicFoldersL");
+
+ TInt count(aFolders.MdcaCount());
+ for (TInt i = 0; i < count; ++i)
+ {
+ TPtrC16 folder = aFolders.MdcaPoint(i);
+
+ // check if disk is inserted and act accordingly
+ TDriveUnit driveUnit(folder);
+ if (!iFs.IsValidDrive(driveUnit))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // append the drive to the drive list
+ iDbDrives.AppendL(driveUnit);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::DbCategoryL
+// ----------------------------------------------------------------------------
+//
+CMPXDbCategory* CMPXDbHandler::DbCategoryL(
+ TMPXGeneralCategory aCategory) const
+ {
+ MPX_FUNC("CMPXDbHandler::DbCategoryL");
+
+ CMPXDbCategory* dbCategory(NULL);
+ switch (aCategory)
+ {
+ case EMPXArtist:
+ {
+ dbCategory = (CMPXDbCategory*)iDbArtist;
+ break;
+ }
+ case EMPXAlbum:
+ {
+ dbCategory = (CMPXDbCategory*)iDbAlbum;
+ break;
+ }
+ case EMPXGenre:
+ {
+ dbCategory = (CMPXDbCategory*)iDbGenre;
+ break;
+ }
+ case EMPXComposer:
+ {
+ dbCategory = (CMPXDbCategory*)iDbComposer;
+ break;
+ }
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ case EMPXAbstractAlbum:
+ {
+ dbCategory = (CMPXDbCategory*)iDbAbstractAlbum;
+ break;
+ }
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+ default:
+ User::Leave(KErrNotSupported);
+ }
+
+ return dbCategory;
+ }
+
+// ----------------------------------------------------------------------------
+// Verifies that the volume ID of the database matches the drive
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::VerifyVolumeIdL( TInt aDrive )
+ {
+ MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL <--");
+ if( iDbManager->IsOpen( aDrive ) )
+ {
+ TVolumeInfo volInfo;
+ iFs.Volume(volInfo, aDrive );
+ TUint curId(volInfo.iUniqueID);
+
+ TInt volId = iDbAuxiliary->IdL( aDrive );
+
+ // New database, no volume id set, mask out top bit because this is an uint
+ //
+ MPX_DEBUG3("CMPXDBHandler::VerifyVolumeIdL drive:%i db:%i", curId, volId);
+ if( volId == 0 && (curId&0x7FFFFFFF) )
+ {
+ MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -- New ID");
+ BeginTransactionL();
+ TRAPD( err, iDbAuxiliary->SetIdL( aDrive, curId&0x7FFFFFFF ) );
+ EndTransactionL( err );
+
+ // KSqlDbCorrupted indicates DB corrupted, need to recreate.
+ if ( err == KSqlDbCorrupted )
+ {
+ MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- Corrupted DB");
+ iDbManager->RecreateDatabaseL(aDrive);
+ BeginTransactionL();
+ TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
+ EndTransactionL( err );
+ }
+ }
+ // Unmatched volume id, mark db as corrupt and break
+ //
+ else if ( (curId&0x7FFFFFFF) != (volId&0x7FFFFFFFF) )
+ {
+ MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -- ID match FAILED");
+ iDbManager->RecreateDatabaseL(aDrive);
+ BeginTransactionL();
+ TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
+ EndTransactionL( err );
+ }
+ }
+
+ MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -->");
+ }
+
+// ----------------------------------------------------------------------------
+// Verifies that the volume ID of the database matches the drive
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::VerifyVolumeIdL()
+ {
+ MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL <--");
+ TInt count( iDbDrives.Count() );
+ for( TInt i=0; i<count; ++i )
+ {
+ VerifyVolumeIdL(iDbDrives[i]);
+ }
+ MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -->");
+ }
+
+
+// ----------------------------------------------------------------------------
+// Checks if there is a drive that has a low disk space
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::CheckDiskSpaceOnDrivesL()
+ {
+ MPX_DEBUG1("CMPXDbHandler::CheckDiskSpaceOnDrivesL <--");
+
+ TInt count( iDbDrives.Count() );
+ for( TInt index=0; index<count; ++index )
+ {
+ iDbManager->CheckDiskSpaceL(iDbDrives[index]);
+ }
+ MPX_DEBUG1("CMPXDbHandler::CheckDiskSpaceOnDrivesL -->");
+ }
+
+#if defined (__MTP_PROTOCOL_SUPPORT)
+
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::SaveDeletedSongs
+// ----------------------------------------------------------------------------
+//
+TBool CMPXDbHandler::SaveDeletedSongs()
+ {
+ MPX_FUNC("CMPXDbHandler::SaveDeletedSongs");
+
+ TBool saveDeletedSongs(ETrue);
+ CRepository* cenrep(NULL);
+ MPX_TRAPD(error, cenrep = CRepository::NewL(KMPXMtpSettings));
+ if (!error)
+ {
+ cenrep->Get(KMPXMtpSaveDeletedRecordFlag, saveDeletedSongs);
+ delete cenrep;
+ MPX_DEBUG2("MTP indicated to save deleted songs? %d", saveDeletedSongs);
+ }
+
+ return saveDeletedSongs;
+ }
+
+#endif
+
+#ifdef RD_MULTIPLE_DRIVE
+
+// ----------------------------------------------------------------------------------------------------------
+// Retrieve all visible music folder locations
+// ----------------------------------------------------------------------------------------------------------
+//
+CDesCArrayFlat* CMPXDbHandler::GetMusicFoldersL()
+ {
+ MPX_FUNC("CMPXDbHandler::GetMusicFoldersL()");
+ TDriveList driveList;
+ TInt driveCount(0);
+ User::LeaveIfError(DriveInfo::GetUserVisibleDrives(iFs, driveList, driveCount));
+ MPX_DEBUG2 ("CMPXDbHandler::GetMusicFoldersL() - driveCount = %d", driveCount);
+
+ CDesCArrayFlat* folders = new (ELeave) CDesCArrayFlat(1); // granularity
+ CleanupStack::PushL(folders);
+
+ for (TInt i = EDriveA; i <= EDriveZ; i++)
+ {
+ if ((driveList[i]) && (!IsRemoteDrive(static_cast<TDriveNumber>(i))))
+ {
+ if (i == EDriveC)
+ {
+ // Append the default phone memory path to the list
+ // of music folders
+ TPtrC rootPath(PathInfo::PhoneMemoryRootPath());
+ folders->AppendL(rootPath);
+ MPX_DEBUG2("CMPXDbHandler::GetMusicFoldersL() - adding...%S", &rootPath);
+ }
+ else
+ {
+ // Get drive letter
+ TChar driveChar;
+ User::LeaveIfError(iFs.DriveToChar(i, driveChar));
+
+ // Append visible drive to list of music folders
+ TBuf<2> drive;
+ drive.Append(driveChar);
+ drive.Append(_L(":"));
+ folders->AppendL(drive);
+ MPX_DEBUG2 ("CMPXDbHandler::GetMusicFoldersL() - adding...%S", &drive);
+ }
+ }
+ }
+
+ CleanupStack::Pop(folders);
+ return folders;
+ }
+
+#endif // RD_MULTIPLE_DRIVE
+
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::AddCategoryItemL
+// ----------------------------------------------------------------------------
+//
+TUint32 CMPXDbHandler::AddCategoryItemL(
+ TMPXGeneralCategory aCategory,
+ const TDesC& aName,
+ TInt aDriveId,
+ CMPXMessageArray* aItemChangedMessages,
+ TBool& aItemExist
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ ,const TDesC& aUri
+ ,const TDesC& aAlbumArtist
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+ )
+ {
+ MPX_FUNC("CMPXDbHandler::AddCategoryItemL()");
+
+ MPX_PERF_START(CMPXDbHandler_AddCategoryItemL);
+
+ TBool newRecord(EFalse);
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ TUint32 id(0);
+ //for AbstractAlbum, SetAbstractAlbum, associate songs with abstractalbum.
+ //only called with newRecord as EFalse
+ //increment songCount if id exist in AbstractAlbum table, otherwise do nothing.
+
+ //only Genre, AbstractAlbum are not case sensitive
+ TBool caseSensitive = ETrue;
+ if ((aCategory == EMPXGenre) || (aCategory == EMPXAbstractAlbum))
+ caseSensitive = EFalse;
+
+ if (aCategory == EMPXAbstractAlbum)
+ {
+ id = iDbAbstractAlbum->AddItemL(aUri, aName, aAlbumArtist, aDriveId, newRecord, caseSensitive);
+ }
+ else
+ {
+ id = DbCategoryL(aCategory)->AddItemL(aName, aDriveId, newRecord, caseSensitive);
+#else
+ TUint32 id(DbCategoryL(aCategory)->AddItemL(aName, aDriveId, newRecord, (aCategory != EMPXGenre)));
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+
+ if (newRecord && aItemChangedMessages)
+ {
+ MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemInserted,
+ aCategory, KDBPluginUid);
+ }
+ // when the added item's category is Genre or Composer,
+ // and it is NOT a new record,
+ // we should send the item number changed message
+ else if ( ( aCategory == EMPXGenre || aCategory == EMPXComposer ) &&
+ !newRecord && aItemChangedMessages )
+ {
+ MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemModified,
+ aCategory, KDBPluginUid);
+ }
+ aItemExist = !newRecord;
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+ }
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+ MPX_PERF_END(CMPXDbHandler_AddCategoryItemL);
+ return id;
+ }
+
+TUint32 CMPXDbHandler::AddCategoryItemL(
+ TMPXGeneralCategory aCategory,
+ const TDesC& aName,
+ const TDesC& aArtistName,
+ const TDesC& aArt,
+ TInt aDriveId,
+ CMPXMessageArray* aItemChangedMessages,
+ TBool& aItemExist)
+ {
+ MPX_FUNC("CMPXDbHandler::AddCategoryItemL()");
+
+ MPX_PERF_START(CMPXDbHandler_AddCategoryItemL);
+
+ TBool newRecord(EFalse);
+
+ TUint32 id = 0;
+ if(aCategory == EMPXAlbum)
+ {
+ id = iDbAlbum->AddItemL(aName, aArtistName, aArt, aDriveId, newRecord, (aCategory != EMPXGenre));
+ }
+ else
+ {
+ id = iDbArtist->AddItemL(aName, aArt, aDriveId, newRecord, (aCategory != EMPXGenre));
+ }
+
+ if (newRecord && aItemChangedMessages)
+ {
+ MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemInserted,
+ aCategory, KDBPluginUid);
+ }
+ // when the added item's category is Artist, and it is NOT a new record,
+ // we should send the item number changed message
+ else if ( aCategory == EMPXArtist &&
+ !newRecord && aItemChangedMessages )
+ {
+ MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemModified,
+ aCategory, KDBPluginUid);
+ }
+ aItemExist = !newRecord;
+ MPX_PERF_END(CMPXDbHandler_AddCategoryItemL);
+
+ return id;
+ }
+
+void CMPXDbHandler::UpdateCategoryItemL(
+ TMPXGeneralCategory aCategory,
+ TUint32 aCategoryId,
+ const CMPXMedia& aMedia,
+ TInt aDrive,
+ CMPXMessageArray* aItemChangedMessages)
+ {
+ switch(aCategory)
+ {
+ case EMPXAlbum:
+ iDbAlbum->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
+ break;
+
+ case EMPXArtist:
+ iDbArtist->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
+ break;
+
+ default:
+ DbCategoryL(aCategory)->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
+ break;
+ }
+ }
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::DeleteSongForCategoryL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::DeleteSongForCategoryL(
+ TMPXGeneralCategory aCategory,
+ TUint32 aCategoryId,
+ TInt aDriveId,
+ CMPXMessageArray* aItemChangedMessages,
+ TBool& aItemExist)
+ {
+ MPX_FUNC("CMPXDbHandler::DeleteSongForCategoryL");
+ DbCategoryL(aCategory)->DecrementSongsForCategoryL(aCategoryId, aDriveId,
+ aItemChangedMessages, aItemExist);
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXDbHandler::HandlePlayCountModifiedL
+// ----------------------------------------------------------------------------
+//
+void CMPXDbHandler::HandlePlayCountModifiedL(
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::HandlePlayCountModifiedL");
+
+ TUint32 plId(iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist));
+
+ MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, plId, EMPXItemModified,
+ EMPXSong, KDBPluginUid, plId);
+
+ // Force the deprecated ID attribute
+ aItemChangedMessages[aItemChangedMessages.Count() - 1]->
+ SetTObjectValueL<TMPXItemId>(KMPXMessageMediaDeprecatedId, plId);
+ }
+
+// ----------------------------------------------------------------------------------------------------------
+// CMPXDbHandler::HandlePlaybackTimeModifiedL
+// ----------------------------------------------------------------------------------------------------------
+//
+void CMPXDbHandler::HandlePlaybackTimeModifiedL(
+ CMPXMessageArray& aItemChangedMessages)
+ {
+ MPX_FUNC("CMPXDbHandler::HandlePlaybackTimeModifiedL");
+
+ TUint32 plId(iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist));
+
+ MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, plId, EMPXItemModified,
+ EMPXSong, KDBPluginUid, plId);
+
+ // Force the deprecated ID attribute
+ aItemChangedMessages[aItemChangedMessages.Count() - 1]->
+ SetTObjectValueL<TMPXItemId>(KMPXMessageMediaDeprecatedId, plId);
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMPXDbHandler::IsRemoteDrive
+// ---------------------------------------------------------------------------
+//
+TBool CMPXDbHandler::IsRemoteDrive(TDriveNumber aDrive)
+ {
+ return iDbManager->IsRemoteDrive(aDrive);
+ }
+
+TInt CMPXDbHandler::HandlePlaylistDurationL(TUint32 aPlaylistId)
+ {
+ return GetPlaylistDurationL(aPlaylistId);
+ }
+void CMPXDbHandler::HandlePlaylistInfoL(
+ TUint32 aPlaylistId,
+ TInt& aCount,
+ TInt& aDuration)
+ {
+ MPX_FUNC("CMPXDbHandler::HandlePlaylistInfoL");
+ MPX_DEBUG2("CMPXDbHandler::HandlePlaylistInfoL(0x%x)", aPlaylistId);
+
+ RArray<TMPXAttribute> attributes;
+ CleanupClosePushL(attributes);
+ attributes.AppendL(KMPXMediaGeneralId);
+ attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration));
+
+ CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
+ CleanupStack::PushL(mediaArray);
+
+ GetPlaylistSongsL(aPlaylistId, attributes.Array(), *mediaArray);
+
+ aCount = mediaArray->Count();
+ for (TInt index = 0; index < aCount; ++index)
+ {
+ CMPXMedia* media((*mediaArray)[index]);
+ if (media->IsSupported(KMPXMediaGeneralDuration))
+ {
+ aDuration += media->ValueTObjectL<TInt>(KMPXMediaGeneralDuration);
+ }
+ }
+
+ CleanupStack::PopAndDestroy(mediaArray);
+ CleanupStack::PopAndDestroy(&attributes);
+ }
+
+TInt CMPXDbHandler::HandleGetAlbumsCountForArtistL(TUint32 aArtistId)
+ {
+ return iDbAlbum->GetAlbumsCountForArtistL(aArtistId);
+ }
+
+TBool CMPXDbHandler::HandleIsUnknownArtistL(TUint32 aArtistId)
+ {
+ return iDbArtist->IsUnknownArtistL(aArtistId);
+ }
+
+// ---------------------------------------------------------------------------
+// CMPXDbHandler::HandleArtistForAlbumL
+// ---------------------------------------------------------------------------
+//
+HBufC* CMPXDbHandler::HandleArtistForAlbumL(const TUint32 aAlbumId)
+ {
+
+ TUint32 artistId = iDbMusic->ArtistForAlbumL(aAlbumId);
+ HBufC* artistname = GetNameMatchingIdL(artistId);
+ return artistname;
+ }
+
+// ---------------------------------------------------------------------------
+// CMPXDbHandler::HandleAlbumartForAlbumL
+// ---------------------------------------------------------------------------
+//
+HBufC* CMPXDbHandler::HandleAlbumartForAlbumL(const TUint32 aAlbumId, TPtrC aArt)
+ {
+ return iDbMusic->AlbumartForAlbumL(aAlbumId, aArt);
+ }
+#ifdef ABSTRACTAUDIOALBUM_INCLUDED
+// ----------------------------------------------------------------------------------------------------------
+// CMPXDbHandler::HandleGetAlbumNameForSongL
+// ----------------------------------------------------------------------------------------------------------
+//
+HBufC* CMPXDbHandler::HandleGetAlbumNameFromIdL(TUint32 aId)
+ {
+ return iDbAbstractAlbum->GetUriL(aId);
+ }
+#endif // ABSTRACTAUDIOALBUM_INCLUDED
+// End of file