mpxplugins/serviceplugins/collectionplugins/mpxsqlitedbplugin/src/mpxdbhandler.cpp
branchRCL_3
changeset 26 3de6c4cf6b67
equal deleted inserted replaced
25:14979e23cb5e 26:3de6c4cf6b67
       
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class is used by db plugin for all database related
       
    15 *                functionality. The main responsibilities are:
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <bautils.h>
       
    22 #ifdef RD_MULTIPLE_DRIVE
       
    23 #include <driveinfo.h>
       
    24 #include <pathinfo.h>
       
    25 #endif //RD_MULTIPLE_DRIVE
       
    26 
       
    27 #include <mpxcollectiondbres.rsg>
       
    28 #include <mpxmediageneraldefs.h>
       
    29 #include <mpxmediacontainerdefs.h>
       
    30 #include <mpxmediamusicdefs.h>
       
    31 #include <mpxmediaaudiodefs.h>
       
    32 #include <mpxmedia.h>
       
    33 #include <mpxmediaarray.h>
       
    34 #include <mpxcollectionpath.h>
       
    35 #include <mpxlog.h>
       
    36 
       
    37 #include "mpxresource.h"
       
    38 #include "mpxdbcommonutil.h"
       
    39 
       
    40 #include "mpxdbutil.h"
       
    41 #include "mpxcollectiondbdef.h"
       
    42 #include "mpxdbpluginqueries.h"
       
    43 #include "mpxcollectiondbmanager.h"
       
    44 #include "mpxdbplaylist.h"
       
    45 #include "mpxdbplaylistsongs.h"
       
    46 #include "mpxdbcategory.h"
       
    47 #include "mpxdbauxiliary.h"
       
    48 #include "mpxdbautoplaylist.h"
       
    49 #include "mpxdbhandler.h"
       
    50 #include "mpxdbartist.h"
       
    51 #include "mpxdbalbum.h"
       
    52 #include "mpxdbgenre.h"
       
    53 #include "mpxdbcomposer.h"
       
    54 
       
    55 // CONSTANTS
       
    56 _LIT(KMPXVirtualPlaylistExt, ".vir");
       
    57 static const TInt KMaxOpInTransaction = 100;
       
    58 
       
    59 const TInt KSqlDbCorrupted = -321;
       
    60 
       
    61 #if defined (__MTP_PROTOCOL_SUPPORT)
       
    62 
       
    63 #include <centralrepository.h>
       
    64 
       
    65 // MTP CenRep Key UID
       
    66 const TUid KMPXMtpSettings = {0x101FFC53};
       
    67 // MTP CenRep Key for Delete contents
       
    68 const TUint32 KMPXMtpSaveDeletedRecordFlag = 0x00000001;
       
    69 
       
    70 #endif
       
    71 
       
    72 // ============================ MEMBER FUNCTIONS ==============================
       
    73 
       
    74 // ----------------------------------------------------------------------------
       
    75 // Two-phased constructor.
       
    76 // ----------------------------------------------------------------------------
       
    77 //
       
    78 CMPXDbHandler* CMPXDbHandler::NewL(
       
    79     RFs& aFs,
       
    80     CMPXResource& aResource)
       
    81     {
       
    82     MPX_FUNC("CMPXDbHandler::NewL");
       
    83     CMPXDbHandler* self = CMPXDbHandler::NewLC(aFs, aResource);
       
    84     CleanupStack::Pop(self);
       
    85     return self;
       
    86     }
       
    87 
       
    88 // ----------------------------------------------------------------------------
       
    89 // Two-phased constructor.
       
    90 // ----------------------------------------------------------------------------
       
    91 //
       
    92 CMPXDbHandler* CMPXDbHandler::NewLC(
       
    93     RFs& aFs,
       
    94     CMPXResource& aResource)
       
    95     {
       
    96     MPX_FUNC("CMPXDbHandler::NewLC");
       
    97     CMPXDbHandler* self = new (ELeave) CMPXDbHandler(aFs, aResource);
       
    98     CleanupStack::PushL(self);
       
    99     self->ConstructL();
       
   100     return self;
       
   101     }
       
   102 
       
   103 // ----------------------------------------------------------------------------
       
   104 // Destructor
       
   105 // ----------------------------------------------------------------------------
       
   106 //
       
   107 CMPXDbHandler::~CMPXDbHandler()
       
   108     {
       
   109     MPX_FUNC("CMPXDbHandler::~CMPXDbHandler");
       
   110 
       
   111     delete iAutoPlaylist;
       
   112 
       
   113     delete iDbMusic;
       
   114     delete iDbPlaylist;
       
   115     delete iDbArtist;
       
   116     delete iDbAlbum;
       
   117     delete iDbGenre;
       
   118     delete iDbComposer;
       
   119     delete iDbAuxiliary;
       
   120     delete iDbManager;
       
   121 
       
   122     delete iMimeTypes;
       
   123     delete iExtensions;
       
   124     delete iExtensionsMime;
       
   125     delete iExtensionsDrm;
       
   126 
       
   127     iDbDrives.Close();
       
   128     }
       
   129 
       
   130 // ----------------------------------------------------------------------------
       
   131 // C++ default constructor can NOT contain any code, that might leave
       
   132 // ----------------------------------------------------------------------------
       
   133 //
       
   134 CMPXDbHandler::CMPXDbHandler(
       
   135     RFs& aFs,
       
   136     CMPXResource& aResource) :
       
   137     iFs(aFs),
       
   138     iResource(aResource)
       
   139     {
       
   140     MPX_FUNC("CMPXDbHandler::CMPXDbHandler");
       
   141     }
       
   142 
       
   143 // ----------------------------------------------------------------------------
       
   144 // Symbian 2nd phase constructor can leave.
       
   145 // ----------------------------------------------------------------------------
       
   146 //
       
   147 void CMPXDbHandler::ConstructL()
       
   148     {
       
   149     MPX_FUNC("CMPXDbHandler::ConstructL");
       
   150 
       
   151     iMimeTypes = iResource.ReadDesCArrayL(R_MC_MIME_TYPES);
       
   152     iExtensions = iResource.ReadDesCArrayL(R_MC_MUSIC_FILE_EXTENSIONS);
       
   153     iExtensionsMime = iResource.ReadDesCArrayL(R_MC_FILE_EXTENSIONS_MIME);
       
   154     iExtensionsDrm = iResource.ReadDesCArrayL(R_MC_FILE_EXTENSIONS_DRM);
       
   155     
       
   156     // make sure all databases are created and valid
       
   157     iDbManager = CMPXCollectionDbManager::NewL(iFs);
       
   158     
       
   159     CDesCArrayFlat* musicFolders =
       
   160 #ifdef RD_MULTIPLE_DRIVE
       
   161         GetMusicFoldersL();
       
   162 #else
       
   163         iResource.ReadDesCArrayL(R_MC_DEFAULT_MUSIC_FOLDERS);
       
   164 #endif
       
   165 
       
   166     // create the music folders and initialize iDbDrives
       
   167     CleanupStack::PushL(musicFolders);
       
   168     ProcessMusicFoldersL(*musicFolders);
       
   169     CleanupStack::PopAndDestroy(musicFolders);
       
   170 
       
   171     // Create the db infrastructure, 
       
   172     //
       
   173     iDbMusic = CMPXDbMusic::NewL(*iDbManager, iResource, *this);
       
   174     iDbPlaylist = CMPXDbPlaylist::NewL(*iDbManager, *this);
       
   175     iDbArtist = CMPXDbArtist::NewL(*iDbManager, EMPXArtist, *this);
       
   176 	iDbAlbum = CMPXDbAlbum::NewL(*iDbManager, EMPXAlbum, *this);
       
   177     iDbGenre = CMPXDbGenre::NewL(*iDbManager, EMPXGenre);
       
   178     iDbComposer = CMPXDbComposer::NewL(*iDbManager, EMPXComposer);
       
   179     iAutoPlaylist = CMPXDbAutoPlaylist::NewL(*iDbManager, iFs, iResource);
       
   180     iDbAuxiliary = CMPXDbAuxiliary::NewL(*iDbManager);
       
   181 
       
   182     MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
       
   183     iCollectionOpen = ETrue;
       
   184 
       
   185     // If KErrCorrupt is returned, a database file was found to be corrupted
       
   186     // and was replaced with a new one.  The db plugin can ignore this error and continue
       
   187     // because a new db file was successfully created in a subsequent retry.
       
   188     if ((err != KErrNone) && (err != KErrCorrupt) && (err != KErrDiskFull))
       
   189         {
       
   190         // leave to signal the caller that there was an error why creating and opening
       
   191         // one or more of the databases
       
   192         User::Leave(err);
       
   193         }
       
   194     else if (err == KErrDiskFull)
       
   195         {
       
   196         iOutOfDisk = ETrue;
       
   197         }
       
   198     else
       
   199         {
       
   200         // do nothing
       
   201         }
       
   202 
       
   203     // Verify the volume ids of each drive matches the database
       
   204     MPX_TRAP(err,VerifyVolumeIdL());
       
   205     if ((err != KErrNone) && (err != KErrDiskFull))
       
   206         {
       
   207         // leave to signal the caller that there was an error why creating and opening
       
   208         // one or more of the databases
       
   209         User::Leave(err);
       
   210         }
       
   211     else if (err == KErrDiskFull)
       
   212         {
       
   213         iOutOfDisk = ETrue;
       
   214         }
       
   215 
       
   216 //#ifdef _DEBUG
       
   217 //    iDbManager->PrintDatabaseL();    // PREQ2536 the files sqlrowsetutil.h and sqlrowsetutil.cpp has been removed
       
   218 //#endif
       
   219 
       
   220     MPX_DEBUG2("CMPXDbHandler::ConstructL DbCount[%d]", iDbManager->DatabaseCount());
       
   221     }
       
   222 
       
   223 // ----------------------------------------------------------------------------
       
   224 // Add song to collection
       
   225 // ----------------------------------------------------------------------------
       
   226 //
       
   227 TUint32 CMPXDbHandler::AddSongL(
       
   228     const CMPXMedia& aMedia,
       
   229     CMPXMessageArray* aMessageArray)
       
   230     {
       
   231     MPX_FUNC("CMPXDbHandler::AddSongL");
       
   232 
       
   233     BeginTransactionL();
       
   234     TUint32 songId(0);
       
   235     MPX_TRAPD(err, songId = DoAddSongL(aMedia,aMessageArray));
       
   236 
       
   237     if (iOutOfDisk && (err == KErrNotFound))
       
   238         {
       
   239         err = KErrDiskFull;
       
   240         }
       
   241     EndTransactionL(err);
       
   242 
       
   243     return songId;
       
   244     }
       
   245 
       
   246 // ----------------------------------------------------------------------------
       
   247 // Add song to collection with no database transaction
       
   248 // ----------------------------------------------------------------------------
       
   249 //
       
   250 TUint32 CMPXDbHandler::AddSongWithNoTransactionL(
       
   251     const CMPXMedia& aMedia,
       
   252     CMPXMessageArray* aMessageArray)
       
   253     {
       
   254     MPX_FUNC("CMPXDbHandler::AddSongWithNoTransactionL");
       
   255 
       
   256     TUint32 songId(0);
       
   257     MPX_TRAPD(err, songId = DoAddSongL(aMedia,aMessageArray));
       
   258 
       
   259     if (iOutOfDisk && (err == KErrNotFound))
       
   260         {
       
   261         err = KErrDiskFull;
       
   262         }
       
   263     User::LeaveIfError(err);
       
   264 
       
   265     return songId;
       
   266     }
       
   267 
       
   268 // ----------------------------------------------------------------------------
       
   269 // Add playlist to collection
       
   270 // ----------------------------------------------------------------------------
       
   271 //
       
   272 TUint32 CMPXDbHandler::AddPlaylistL(
       
   273     const CMPXMedia& aMedia)
       
   274     {
       
   275     MPX_FUNC("CMPXDbHandler::AddPlaylistL");
       
   276 
       
   277     BeginTransactionL();
       
   278     TUint32 playlistId(0);
       
   279     MPX_TRAPD(err, playlistId = DoAddPlaylistL(aMedia));
       
   280     EndTransactionL(err);
       
   281 
       
   282     return playlistId;
       
   283     }
       
   284 
       
   285 // ----------------------------------------------------------------------------
       
   286 // Add song to playlist
       
   287 // ----------------------------------------------------------------------------
       
   288 //
       
   289 TUint32 CMPXDbHandler::AddSongToPlaylistL(
       
   290     const CMPXMedia& aMedia)
       
   291     {
       
   292     MPX_FUNC("CMPXDbHandler::AddSongToPlaylistL");
       
   293 
       
   294     BeginTransactionL();
       
   295     TUint32 playlistId(0);
       
   296     MPX_TRAPD(err, playlistId = DoAddSongToPlaylistL(aMedia));
       
   297     EndTransactionL(err);
       
   298 
       
   299     return playlistId;
       
   300     }
       
   301 
       
   302 // ----------------------------------------------------------------------------
       
   303 // Update a song in the collection
       
   304 // ----------------------------------------------------------------------------
       
   305 //
       
   306 CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::UpdateSongL(
       
   307     const CMPXMedia& aMedia,
       
   308     CMPXMessageArray& aItemChangedMessages)
       
   309     {
       
   310     MPX_FUNC("CMPXDbHandler::UpdateSongL");
       
   311 
       
   312     BeginTransactionL();
       
   313     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
   314     MPX_TRAPD(err, visibleChange = DoUpdateSongL(aMedia, aItemChangedMessages));
       
   315     EndTransactionL(err);
       
   316     return visibleChange;
       
   317     }
       
   318 
       
   319 // ----------------------------------------------------------------------------
       
   320 // Update a playlist in the collection
       
   321 // ----------------------------------------------------------------------------
       
   322 //
       
   323 void CMPXDbHandler::UpdatePlaylistL(
       
   324     const CMPXMedia& aMedia,
       
   325     CMPXMessageArray& aMessageArray)
       
   326     {
       
   327     MPX_FUNC("CMPXDbHandler::UpdatePlaylistL");
       
   328 
       
   329     BeginTransactionL();
       
   330     MPX_TRAPD(err, DoUpdatePlaylistL(aMedia, aMessageArray));
       
   331     EndTransactionL(err);
       
   332     }
       
   333 
       
   334 // ----------------------------------------------------------------------------
       
   335 // Updates the playlist songs
       
   336 // ----------------------------------------------------------------------------
       
   337 //
       
   338 void CMPXDbHandler::UpdatePlaylistSongsL(
       
   339     const CMPXMedia& aMedia,
       
   340     CMPXMessage& aMessage)
       
   341     {
       
   342     MPX_FUNC("CMPXDbHandler::UpdatePlaylistSongsL");
       
   343 
       
   344     BeginTransactionL();
       
   345     MPX_TRAPD(err, DoUpdatePlaylistSongsL(aMedia, aMessage));
       
   346     EndTransactionL(err);
       
   347     }
       
   348 
       
   349 // ----------------------------------------------------------------------------
       
   350 // Reorder a song in a playlist
       
   351 // ----------------------------------------------------------------------------
       
   352 //
       
   353 void CMPXDbHandler::ReorderPlaylistL(
       
   354     const TMPXItemId& aPlaylistId,
       
   355     const TMPXItemId& aSongId,
       
   356     TUint aOriginalOrdinal,
       
   357     TUint aNewOrdinal,
       
   358     CMPXMessage& aMessage)
       
   359     {
       
   360     MPX_DEBUG5("-->CMPXDbHandler::ReorderPlaylistL(0x%x, 0x%x, %d, %d)",
       
   361                aPlaylistId.iId2, aSongId.iId2, aOriginalOrdinal, aNewOrdinal);
       
   362 
       
   363     BeginTransactionL();
       
   364     MPX_TRAPD(err, DoReorderPlaylistL(aPlaylistId, aSongId, aOriginalOrdinal, aNewOrdinal, aMessage));
       
   365     EndTransactionL(err);
       
   366     MPX_DEBUG2("<--CMPXDbHandler::ReorderPlaylistL() error=%d", err);
       
   367     }
       
   368 
       
   369 // ----------------------------------------------------------------------------
       
   370 // Remove the entire music collection database
       
   371 // ----------------------------------------------------------------------------
       
   372 //
       
   373 void CMPXDbHandler::RemoveEntireCollectionL()
       
   374     {
       
   375     MPX_FUNC("CMPXDbHandler::RemoveEntireCollectionL");
       
   376     BeginTransactionL();
       
   377     MPX_TRAPD(err, iDbManager->RecreateAllDatabasesL());
       
   378     EndTransactionL(err);
       
   379     }
       
   380 
       
   381 // ----------------------------------------------------------------------------
       
   382 // Delete a song from collection
       
   383 // The function notifies collection model to perform deletion
       
   384 // ----------------------------------------------------------------------------
       
   385 //
       
   386 void CMPXDbHandler::RemoveSongL(
       
   387     TUint32 aSongId,
       
   388     CDesCArray& aUriArray,
       
   389     CMPXMessageArray& aItemChangedMessages,
       
   390     TBool aDeleteRecord)
       
   391     {
       
   392     MPX_FUNC("CMPXDbHandler::RemoveSongL");
       
   393 
       
   394     MPX_TRAPD(err, DoRemoveSongL(aSongId, aUriArray, aItemChangedMessages, aDeleteRecord));
       
   395 
       
   396     MPX_TRAP(err, DoRemoveSongFromPlaylistL(aSongId,aItemChangedMessages));
       
   397 
       
   398     }
       
   399 
       
   400 // ----------------------------------------------------------------------------
       
   401 // Removes a category of songs from the music collection,
       
   402 // and its corresponding category in the lookup table
       
   403 // ----------------------------------------------------------------------------
       
   404 //
       
   405 void CMPXDbHandler::RemoveSongsMatchingCategoryL(
       
   406     TMPXGeneralCategory aCategory,
       
   407     TUint32 aCategoryId,
       
   408     CDesCArray& aUriArray,
       
   409     CMPXMessageArray& aItemChangedMessages)
       
   410     {
       
   411     MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingCategoryL");
       
   412 
       
   413     BeginTransactionL();
       
   414     MPX_TRAPD(err, DoRemoveSongsMatchingCategoryL(aCategory, aCategoryId, aUriArray, aItemChangedMessages));
       
   415     EndTransactionL(err);
       
   416     }
       
   417 
       
   418 // ----------------------------------------------------------------------------------------------------------
       
   419 // Delete songs for the specified artist and album from collection
       
   420 // The function notifies collection model to perform deletion
       
   421 // ----------------------------------------------------------------------------------------------------------
       
   422 //
       
   423 void CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL(
       
   424     TUint32 aArtistId,
       
   425     TUint32 aAlbumId,
       
   426     CDesCArray& aUriArray,
       
   427     CMPXMessageArray& aItemChangedMessages)
       
   428     {
       
   429     MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL");
       
   430 
       
   431     BeginTransactionL();
       
   432     MPX_TRAPD(err, DoRemoveSongsMatchingArtistAndAlbumL(aArtistId, aAlbumId, aUriArray,
       
   433         aItemChangedMessages));
       
   434     EndTransactionL(err);
       
   435     }
       
   436 
       
   437 // ----------------------------------------------------------------------------
       
   438 // Remove all playlists from collection
       
   439 // ----------------------------------------------------------------------------
       
   440 //
       
   441 void CMPXDbHandler::RemoveAllPlaylistsL()
       
   442     {
       
   443     MPX_FUNC("CMPXDbHandler::RemoveAllPlaylistsL");
       
   444 
       
   445     BeginTransactionL();
       
   446     MPX_TRAPD(err, DoRemoveAllPlaylistsL());
       
   447     EndTransactionL(err);
       
   448     }
       
   449 
       
   450 // ----------------------------------------------------------------------------
       
   451 // Remove specified playlist
       
   452 // ----------------------------------------------------------------------------
       
   453 //
       
   454 void CMPXDbHandler::RemovePlaylistL(
       
   455     TUint32 aPlaylistId,
       
   456     CDesCArray& aUriArray,
       
   457     CMPXMessageArray& aItemChangedMessages)
       
   458     {
       
   459     MPX_FUNC("CMPXDbHandler::RemovePlaylistL");
       
   460 
       
   461     BeginTransactionL();
       
   462     MPX_TRAPD(err, DoRemovePlaylistL(aPlaylistId, aUriArray, aItemChangedMessages));
       
   463     EndTransactionL(err);
       
   464     }
       
   465 
       
   466 // ----------------------------------------------------------------------------
       
   467 // Remove song from playlist songs table
       
   468 // ----------------------------------------------------------------------------
       
   469 //
       
   470 void CMPXDbHandler::RemoveSongFromPlaylistL(
       
   471     TUint32 aPlaylistId,
       
   472     const TMPXItemId& aSongId,
       
   473     TInt aOrdinal,
       
   474     CMPXMessageArray& aItemChangedMessages)
       
   475     {
       
   476     MPX_FUNC("CMPXDbHandler::RemoveSongFromPlaylistL");
       
   477     MPX_DEBUG5("CMPXDbHandler::RemoveSongFromPlaylistL(playlist 0x%x, songId [0x%x,0x%x], ordinal %d)",
       
   478         aPlaylistId, aSongId.iId1, aSongId.iId2, aOrdinal);
       
   479 
       
   480     MPX_TRAPD(err, DoRemoveSongFromPlaylistL(aPlaylistId, aSongId, aOrdinal, aItemChangedMessages));
       
   481     if ( err && InTransaction() )
       
   482         {
       
   483         // only end transaction if there's an error
       
   484         EndTransactionL( err );
       
   485         }
       
   486     }
       
   487 
       
   488 // ----------------------------------------------------------------------------
       
   489 // Cleanup records marked as deleted. This is designated for MTP to clean up records marked as deleted
       
   490 // at the end of its session.
       
   491 // ----------------------------------------------------------------------------
       
   492 //
       
   493 void CMPXDbHandler::CleanupDeletedRecordsL()
       
   494     {
       
   495     MPX_FUNC("CMPXDbHandler::CleanupDeletedRecordsL");
       
   496 
       
   497     BeginTransactionL();
       
   498     MPX_TRAPD(err, DoCleanupDeletedRecordsL());
       
   499     EndTransactionL(err);
       
   500     }
       
   501 
       
   502 // ----------------------------------------------------------------------------
       
   503 //  Read all songs and cache them into an array ordered by song name
       
   504 // ----------------------------------------------------------------------------
       
   505 //
       
   506 void CMPXDbHandler::GetAllSongsL(
       
   507     CMPXMediaArray* aMediaArray,
       
   508     const TArray<TMPXAttribute>& aAttrs)
       
   509     {
       
   510     MPX_FUNC("CMPXDbHandler::GetAllSongsL");
       
   511     iDbMusic->GetAllSongsL(aAttrs, *aMediaArray);
       
   512     }
       
   513 
       
   514 // ----------------------------------------------------------------------------
       
   515 //  Read a limited # of songs and cache them into an array ordered by song name
       
   516 // ----------------------------------------------------------------------------
       
   517 //
       
   518 void CMPXDbHandler::GetAllSongsLimitedL(const TArray<TMPXAttribute>& aAttrs,
       
   519                                         CMPXMediaArray& aMediaArray, TInt aLimit)
       
   520     {
       
   521     MPX_FUNC("CMPXDbHandler::GetAllSongsLimitedL");
       
   522     iDbMusic->GetAllSongsLimitedL( aAttrs, aMediaArray, aLimit );
       
   523     }
       
   524 
       
   525 // ----------------------------------------------------------------------------
       
   526 //  Read all songs and cache them into an array ordered by song name
       
   527 // ----------------------------------------------------------------------------
       
   528 //
       
   529 void CMPXDbHandler::GetSongsInBlockL(
       
   530     CMPXMediaArray* aMediaArray,
       
   531     const TArray<TMPXAttribute>& aAttrs,
       
   532     TPtrC aTitle,
       
   533     TUint aNumOfSongs,
       
   534     TBool aAsc)
       
   535     {
       
   536     MPX_FUNC("CMPXDbHandler::GetSongsInBlockL");
       
   537     iDbMusic->GetSongsInBlockL(aAttrs, *aMediaArray, aTitle, aNumOfSongs, aAsc);
       
   538     }
       
   539 
       
   540 // ----------------------------------------------------------------------------
       
   541 //  Read songs at a particular offset
       
   542 // ----------------------------------------------------------------------------
       
   543 //
       
   544 void CMPXDbHandler::GetSongsAtOffsetL( CMPXMediaArray* aMediaArray,
       
   545                                        const TArray<TMPXAttribute>& aAttrs,
       
   546                                        TInt aOffset,
       
   547                                        TInt aCount )
       
   548     {
       
   549     MPX_DEBUG1("CMPXDbHandler::GetSongsAtOffsetL <--");
       
   550     iDbMusic->GetSongsAtOffsetL( *aMediaArray, aAttrs, aOffset, aCount );
       
   551     }
       
   552 
       
   553 // ----------------------------------------------------------------------------
       
   554 // Get all songs matching the given artist ID
       
   555 // ----------------------------------------------------------------------------
       
   556 //
       
   557 void CMPXDbHandler::GetSongsMatchingArtistL(
       
   558     TUint aArtistId,
       
   559     const TArray<TMPXAttribute>& aAttrs,
       
   560     CMPXMediaArray* aMediaArray)
       
   561     {
       
   562     MPX_FUNC("CMPXDbHandler::GetSongsMatchingArtistL");
       
   563     iDbMusic->GetSongsForArtistL(aArtistId, aAttrs, *aMediaArray);
       
   564     }
       
   565 
       
   566 // ----------------------------------------------------------------------------
       
   567 // Get all songs matching the given album ID
       
   568 // ----------------------------------------------------------------------------
       
   569 //
       
   570 void CMPXDbHandler::GetSongsMatchingAlbumL(
       
   571     TUint aAlbumId,
       
   572     const TArray<TMPXAttribute>& aAttrs,
       
   573     CMPXMediaArray* aMediaArray)
       
   574     {
       
   575     MPX_FUNC("CMPXDbHandler::GetSongsMatchingAlbumL");
       
   576     iDbMusic->GetSongsForAlbumL(aAlbumId, aAttrs, *aMediaArray);
       
   577     }
       
   578 
       
   579 // ----------------------------------------------------------------------------------------------------------
       
   580 // Get all songs matching the given artist and album ID
       
   581 // ----------------------------------------------------------------------------------------------------------
       
   582 //
       
   583 void CMPXDbHandler::GetSongsMatchingArtistAndAlbumL(
       
   584     TUint aArtistId,
       
   585     TUint aAlbumId,
       
   586     const TArray<TMPXAttribute>& aAttrs,
       
   587     CMPXMediaArray* aMediaArray)
       
   588     {
       
   589     MPX_FUNC("CMPXDbHandler::GetSongsMatchingArtistAndAlbumL");
       
   590     iDbMusic->GetSongsForArtistAndAlbumL(aArtistId, aAlbumId, aAttrs, *aMediaArray);
       
   591     }
       
   592 
       
   593 // ----------------------------------------------------------------------------
       
   594 // Get all songs matching the given genre ID
       
   595 // ----------------------------------------------------------------------------
       
   596 //
       
   597 void CMPXDbHandler::GetSongsMatchingGenreL(
       
   598     TUint aGenreId,
       
   599     const TArray<TMPXAttribute>& aAttrs,
       
   600     CMPXMediaArray* aMediaArray)
       
   601     {
       
   602     MPX_FUNC("CMPXDbHandler::GetSongsMatchingGenreL");
       
   603     iDbMusic->GetSongsForGenreL(aGenreId, aAttrs, *aMediaArray);
       
   604     }
       
   605 
       
   606 // ----------------------------------------------------------------------------
       
   607 // Get all songs matching the given composer ID
       
   608 // ----------------------------------------------------------------------------
       
   609 //
       
   610 void CMPXDbHandler::GetSongsMatchingComposerL(
       
   611     TUint aComposerId,
       
   612     const TArray<TMPXAttribute>& aAttrs,
       
   613     CMPXMediaArray* aMediaArray)
       
   614     {
       
   615     MPX_FUNC("CMPXDbHandler::GetSongsMatchingComposerL");
       
   616     iDbMusic->GetSongsForComposerL(aComposerId, aAttrs, *aMediaArray);
       
   617     }
       
   618 
       
   619 // ----------------------------------------------------------------------------
       
   620 // Get all songs that belong to the given playlist
       
   621 // ----------------------------------------------------------------------------
       
   622 //
       
   623 void CMPXDbHandler::GetSongsMatchingPlaylistL(
       
   624     TUint aPlaylistId,
       
   625     const TArray<TMPXAttribute>& aAttrs,
       
   626     CMPXMediaArray* aMediaArray)
       
   627     {
       
   628     MPX_FUNC("CMPXDbHandler::GetSongsMatchingPlaylistL");
       
   629     GetPlaylistSongsL(aPlaylistId, aAttrs, *aMediaArray);
       
   630     }
       
   631 
       
   632 // ----------------------------------------------------------------------------
       
   633 // Get song matching the given song ID
       
   634 // ----------------------------------------------------------------------------
       
   635 //
       
   636 void CMPXDbHandler::GetSongL(
       
   637     TUint32 aSongId,
       
   638     const TArray<TMPXAttribute>& aAttrs,
       
   639     CMPXMedia& aMedia)
       
   640     {
       
   641     MPX_FUNC("CMPXDbHandler::GetSongL");
       
   642     iDbMusic->GetSongL(aSongId, aAttrs, aMedia);
       
   643     }
       
   644 
       
   645 // ----------------------------------------------------------------------------
       
   646 // GetSongL
       
   647 // ----------------------------------------------------------------------------
       
   648 //
       
   649 void CMPXDbHandler::GetSongL(
       
   650     TUint32 aSongId,
       
   651     const TArray<TMPXAttribute>& aAttrs,
       
   652     CMPXMediaArray& aMediaArray)
       
   653     {
       
   654     MPX_FUNC("CMPXDbHandler::GetSongL");
       
   655 
       
   656     CMPXMedia* media = CMPXMedia::NewL();
       
   657     CleanupStack::PushL(media);
       
   658 
       
   659     GetSongL(aSongId, aAttrs, *media);
       
   660     aMediaArray.AppendL(*media);
       
   661 
       
   662     CleanupStack::PopAndDestroy(media);
       
   663     }
       
   664 
       
   665 // ----------------------------------------------------------------------------
       
   666 // Get song matching the given song ID and playlist ID
       
   667 // ----------------------------------------------------------------------------
       
   668 //
       
   669 void CMPXDbHandler::GetPlaylistSongL(
       
   670     TUint32 aSongId,
       
   671     TUint32 aPlaylistId,
       
   672     const TArray<TMPXAttribute>& aAttrs,
       
   673     CMPXMedia& aMedia)
       
   674     {
       
   675     MPX_DEBUG3("-->CMPXDbHandler::GetPlaylistSongL songId[0x%x] playlistId[0x%x]", aSongId, aPlaylistId);
       
   676 
       
   677     // complete the song information from the Music table
       
   678     MPX_TRAPD(err, iDbMusic->GetSongL(aSongId, aAttrs, aMedia));
       
   679 
       
   680     //
       
   681     // song not found in Music table
       
   682     //
       
   683     if (err == KErrNotFound)
       
   684         {
       
   685         //
       
   686         // Leave with KErrNotFound if one of the following is true:
       
   687         // 1) the requested song is in an auto playlist. Since auto-playlist isn't
       
   688         //    stored in playlist tables, we won't be able to retrieve info elsewhere
       
   689         // 2) the requested song is in a user playlist but we cannot find the song
       
   690         //    info from playlist tables either
       
   691         //
       
   692         if (EMPXNoAutoPlaylist != iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) ||
       
   693             !iDbPlaylist->Songs().GetSongL(aPlaylistId, aSongId, aAttrs, aMedia))
       
   694             {
       
   695             User::Leave(KErrNotFound);
       
   696             }
       
   697         }
       
   698 
       
   699     //
       
   700     // Unable to read information from Music table
       
   701     //
       
   702     else
       
   703         {
       
   704         // ignore the error if KErrNotFound
       
   705         User::LeaveIfError(err);
       
   706         }
       
   707     MPX_DEBUG1("<--CMPXDbHandler::GetPlaylistSongL");
       
   708     }
       
   709 
       
   710 // ----------------------------------------------------------------------------
       
   711 // GetPlaylistSongL
       
   712 // ----------------------------------------------------------------------------
       
   713 //
       
   714 void CMPXDbHandler::GetPlaylistSongL(
       
   715     TUint32 aSongId,
       
   716     TUint32 aPlaylistId,
       
   717     const TArray<TMPXAttribute>& aAttrs,
       
   718     CMPXMediaArray& aMediaArray)
       
   719     {
       
   720     MPX_FUNC("CMPXDbHandler::GetPlaylistSongL");
       
   721 
       
   722     CMPXMedia* media = CMPXMedia::NewL();
       
   723     CleanupStack::PushL(media);
       
   724 
       
   725     GetPlaylistSongL(aSongId, aPlaylistId, aAttrs, *media);
       
   726     aMediaArray.AppendL(*media);
       
   727 
       
   728     CleanupStack::PopAndDestroy(media);
       
   729     }
       
   730 
       
   731 // ----------------------------------------------------------------------------
       
   732 // Get song matching the given URI
       
   733 // ----------------------------------------------------------------------------
       
   734 //
       
   735 TUint32 CMPXDbHandler::GetSongIdMatchingUriL(
       
   736     const TDesC& aUri)
       
   737     {
       
   738     MPX_FUNC("CMPXDbHandler::GetSongIdMatchingUriL");
       
   739     return MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, aUri, EFalse);
       
   740     }
       
   741 
       
   742 // ----------------------------------------------------------------------------
       
   743 // Get all artists
       
   744 // ----------------------------------------------------------------------------
       
   745 //
       
   746 void CMPXDbHandler::GetAllArtistsL(
       
   747     const TArray<TMPXAttribute>& aAttrs,
       
   748     CMPXMediaArray* aMediaArray)
       
   749     {
       
   750     MPX_FUNC("CMPXDbHandler::GetAllArtistsL");
       
   751     iDbArtist->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
   752     }
       
   753 
       
   754 // ----------------------------------------------------------------------------
       
   755 // Get all albums
       
   756 // ----------------------------------------------------------------------------
       
   757 //
       
   758 void CMPXDbHandler::GetAllAlbumsL(
       
   759     const TArray<TMPXAttribute>& aAttrs,
       
   760     CMPXMediaArray* aMediaArray)
       
   761     {
       
   762     MPX_FUNC("CMPXDbHandler::GetAllAlbumsL");
       
   763     iDbAlbum->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
   764     }
       
   765 
       
   766 // ----------------------------------------------------------------------------
       
   767 // Get all albums for the given artist ID
       
   768 // ----------------------------------------------------------------------------
       
   769 //
       
   770 void CMPXDbHandler::GetAlbumsMatchingArtistL(
       
   771     TUint aArtistId,
       
   772     const TArray<TMPXAttribute>& aAttrs,
       
   773     CMPXMediaArray& aMediaArray)
       
   774     {
       
   775     MPX_FUNC("CMPXDbHandler::GetAlbumsMatchingArtistL");
       
   776     RArray<TMPXAttribute> attributes;
       
   777     CleanupClosePushL( attributes );
       
   778         
       
   779     TBool tryGetSongCount = EFalse;
       
   780     TInt attrCount(aAttrs.Count());
       
   781     TInt i = 0;
       
   782     for (i = 0; i < attrCount; i++)
       
   783         {
       
   784         TInt contentId(aAttrs[i].ContentId());
       
   785         TUint attributeId(aAttrs[i].AttributeId());
       
   786 
       
   787         if (contentId == KMPXMediaIdGeneral && attributeId & EMPXMediaGeneralCount)
       
   788             {
       
   789             MPX_DEBUG1("    EMPXMediaGeneralCount");
       
   790             
       
   791             attributes.Append(TMPXAttribute(KMPXMediaIdGeneral, attributeId & ~EMPXMediaGeneralCount));
       
   792                        
       
   793             tryGetSongCount = ETrue;
       
   794             break;
       
   795             }
       
   796         
       
   797         attributes.Append(aAttrs[i]);
       
   798         }
       
   799     
       
   800     for (TInt j = i+1; j < attrCount; j++)
       
   801         {
       
   802         attributes.Append(aAttrs[j]);
       
   803         }
       
   804     iDbAlbum->GetSubCategoryItemsL(EMPXArtist, aArtistId, attributes.Array(), aMediaArray);
       
   805     CleanupStack::PopAndDestroy(&attributes);
       
   806     
       
   807     TInt pPath(0);
       
   808     if (aMediaArray.Count())
       
   809         {
       
   810         CMPXMedia* pMedia = aMediaArray[0];
       
   811         if (pMedia->IsSupported(KMPXMediaGeneralValue))
       
   812             {
       
   813             pPath = pMedia->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
   814             MPX_ASSERT(pPath);
       
   815             }
       
   816         }
       
   817     
       
   818     TInt albumCount(aMediaArray.Count());
       
   819     if (albumCount)
       
   820         {
       
   821         if ( tryGetSongCount )
       
   822             {
       
   823             TInt startIndex = pPath ? 1 : 0;
       
   824             
       
   825             for (TInt i = startIndex; i < albumCount; i++)
       
   826                 {
       
   827                 CMPXMedia* media = aMediaArray[i];
       
   828                 TUint32 albumId((media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)));
       
   829 
       
   830 				TInt songCount = iDbAlbum->GetSongsCountInAlbumMatchingArtistL(aArtistId, albumId);
       
   831 
       
   832                 media->SetTObjectValueL<TInt>(KMPXMediaGeneralCount, songCount );
       
   833 				MPX_DEBUG2("	SongCount[%d]", songCount );				
       
   834                 }
       
   835             }
       
   836         }
       
   837     }
       
   838 
       
   839 // ----------------------------------------------------------------------------
       
   840 // Get all genres
       
   841 // ----------------------------------------------------------------------------
       
   842 //
       
   843 void CMPXDbHandler::GetAllGenresL(
       
   844     const TArray<TMPXAttribute>& aAttrs,
       
   845     CMPXMediaArray* aMediaArray)
       
   846     {
       
   847     MPX_FUNC("CMPXDbHandler::GetAllGenresL");
       
   848     iDbGenre->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
   849     }
       
   850 
       
   851 // ----------------------------------------------------------------------------
       
   852 // Get all composers
       
   853 // ----------------------------------------------------------------------------
       
   854 //
       
   855 void CMPXDbHandler::GetAllComposersL(
       
   856     const TArray<TMPXAttribute>& aAttrs,
       
   857     CMPXMediaArray* aMediaArray)
       
   858     {
       
   859     MPX_FUNC("CMPXDbHandler::GetAllComposersL");
       
   860     iDbComposer->GetAllCategoryItemsL(aAttrs, *aMediaArray);
       
   861     }
       
   862 
       
   863 // ----------------------------------------------------------------------------
       
   864 // Get the playlist ID of the playlist that matches the given URI
       
   865 // ----------------------------------------------------------------------------
       
   866 //
       
   867 TUint32 CMPXDbHandler::GetPlaylistIdMatchingUriL(
       
   868     const TDesC& aUri)
       
   869     {
       
   870     MPX_FUNC("CMPXDbHandler::GetPlaylistIdMatchingUriL");
       
   871     return iDbPlaylist->GetIdL(aUri);
       
   872     }
       
   873 
       
   874 // ----------------------------------------------------------------------------
       
   875 // CMPXDbHandler::IsAutoPlaylistL
       
   876 // ----------------------------------------------------------------------------
       
   877 //
       
   878 TBool CMPXDbHandler::IsAutoPlaylistL(
       
   879     TUint32 aPlaylistId)
       
   880     {
       
   881     MPX_FUNC("CMPXDbHandler::IsAutoPlaylistL");
       
   882     return (iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) != EMPXNoAutoPlaylist);
       
   883     }
       
   884 
       
   885 // ----------------------------------------------------------------------------
       
   886 // Get all user playlist names
       
   887 // ----------------------------------------------------------------------------
       
   888 //
       
   889 void CMPXDbHandler::GetAllPlaylistsL(
       
   890     CMPXMediaArray* aMediaArray,
       
   891     const TArray<TMPXAttribute>& aAttrs)
       
   892     {
       
   893     MPX_FUNC("CMPXDbHandler::GetAllPlaylistsL");
       
   894     iDbPlaylist->GetAllPlaylistsL(aAttrs, *aMediaArray);
       
   895     }
       
   896 
       
   897 // ----------------------------------------------------------------------------
       
   898 // Get all system playlist names
       
   899 // ----------------------------------------------------------------------------
       
   900 //
       
   901 void CMPXDbHandler::GetAllSystemPlaylistNamesL(
       
   902     CMPXMediaArray* aMediaArray)
       
   903     {
       
   904     MPX_FUNC("CMPXDbHandler::GetAllSystemPlaylistNamesL()");
       
   905     iAutoPlaylist->GetAllPlaylistsL(*aMediaArray);
       
   906     }
       
   907 
       
   908 // ----------------------------------------------------------------------------
       
   909 // Get the name of the row matching the given ID
       
   910 // ----------------------------------------------------------------------------
       
   911 //
       
   912 HBufC* CMPXDbHandler::GetNameMatchingIdL(
       
   913     const TUint32 aId) const
       
   914     {
       
   915     MPX_FUNC("CMPXDbHandler::GetNameMatchingIdL()");
       
   916 
       
   917     HBufC* name(NULL);
       
   918     TMPXGeneralCategory category(MPX_ITEM_CATEGORY(aId));
       
   919     switch (category)
       
   920         {
       
   921         case EMPXCollection:
       
   922             {
       
   923             // song name
       
   924             name = iDbMusic->GetNameL(aId);
       
   925             break;
       
   926             }
       
   927         case EMPXPlaylist:
       
   928             {
       
   929             // playlist name
       
   930             if (iAutoPlaylist->AutoPlaylistTypeL(aId) != EMPXNoAutoPlaylist)
       
   931                 {
       
   932                 name = iAutoPlaylist->AutoPlaylistNameL(aId).AllocL();
       
   933                 }
       
   934             else
       
   935                 {
       
   936                 name = iDbPlaylist->GetNameL(aId);
       
   937                 }
       
   938             break;
       
   939             }
       
   940         default:
       
   941             {
       
   942             // category name
       
   943             name = DbCategoryL(category)->GetNameL(aId);
       
   944             break;
       
   945             }
       
   946         }
       
   947 
       
   948     return name;
       
   949     }
       
   950 
       
   951 // ----------------------------------------------------------------------------
       
   952 // Get the URI of the row matching the given ID
       
   953 // ----------------------------------------------------------------------------
       
   954 //
       
   955 HBufC* CMPXDbHandler::GetUriMatchingIdL(
       
   956     const TUint32 aId) const
       
   957     {
       
   958     MPX_FUNC("CMPXDbHandler::GetUriMatchingIdL");
       
   959 
       
   960     HBufC* uri(NULL);
       
   961     switch (MPX_ITEM_CATEGORY(aId))
       
   962         {
       
   963         case EMPXCollection:
       
   964             {
       
   965             // song URI
       
   966             uri = iDbMusic->GetUriL(aId);
       
   967             break;
       
   968             }
       
   969         case EMPXPlaylist:
       
   970             {
       
   971             // playlist URI
       
   972             uri = iDbPlaylist->GetUriL(aId);
       
   973             break;
       
   974             }
       
   975         default:
       
   976             User::Leave(KErrNotSupported);
       
   977         }
       
   978 
       
   979     return uri;
       
   980     }
       
   981 
       
   982 // ----------------------------------------------------------------------------
       
   983 // Get category
       
   984 // ----------------------------------------------------------------------------
       
   985 //
       
   986 void CMPXDbHandler::GetCategoryL(
       
   987     const TUint32 aCategoryId,
       
   988     TMPXGeneralCategory aCategory,
       
   989     const TArray<TMPXAttribute>& aAttrs,
       
   990     CMPXMedia* aMedia)
       
   991     {
       
   992     MPX_FUNC("CMPXDbHandler::GetCategoryL");
       
   993 
       
   994     switch (aCategory)
       
   995         {
       
   996         case EMPXPlaylist:
       
   997             {
       
   998             if (iAutoPlaylist->AutoPlaylistTypeL(aCategoryId) != EMPXNoAutoPlaylist)
       
   999                 {
       
  1000                 iAutoPlaylist->GetPlaylistL(aCategoryId, aAttrs, *aMedia);
       
  1001                 }
       
  1002             else
       
  1003                 {
       
  1004                 iDbPlaylist->GetPlaylistL(aCategoryId, aAttrs, *aMedia);
       
  1005                 }
       
  1006             break;
       
  1007             }
       
  1008         default:
       
  1009             {
       
  1010             DbCategoryL(aCategory)->GetCategoryItemL(aCategoryId, aAttrs, *aMedia);
       
  1011             break;
       
  1012             }
       
  1013         }
       
  1014     }
       
  1015 
       
  1016 // ----------------------------------------------------------------------------
       
  1017 //  Get the duration for all songs
       
  1018 // ----------------------------------------------------------------------------
       
  1019 //
       
  1020 TInt CMPXDbHandler::GetAllSongsDurationL()
       
  1021     {
       
  1022     MPX_FUNC("CMPXDbHandler::GetAllSongsDurationL");
       
  1023     return iDbMusic->AllSongsDurationL();
       
  1024     }
       
  1025 
       
  1026 // ----------------------------------------------------------------------------
       
  1027 //  Get the duration for an artist
       
  1028 // ----------------------------------------------------------------------------
       
  1029 //
       
  1030 TInt CMPXDbHandler::GetArtistDurationL(
       
  1031     TInt aArtistId)
       
  1032     {
       
  1033     MPX_FUNC("CMPXDbHandler::GetArtistDurationL");
       
  1034     return iDbMusic->ArtistDurationL(aArtistId);
       
  1035     }
       
  1036 
       
  1037 // ----------------------------------------------------------------------------
       
  1038 //  Get the duration for an album
       
  1039 // ----------------------------------------------------------------------------
       
  1040 //
       
  1041 TInt CMPXDbHandler::GetAlbumDurationL(
       
  1042     TInt aAlbumId)
       
  1043     {
       
  1044     MPX_FUNC("CMPXDbHandler::GetAlbumDurationL");
       
  1045     return iDbMusic->AlbumDurationL(aAlbumId);
       
  1046     }
       
  1047 
       
  1048 // ----------------------------------------------------------------------------
       
  1049 //  Get the duration for an artist/album combination
       
  1050 // ----------------------------------------------------------------------------
       
  1051 //
       
  1052 TInt CMPXDbHandler::GetArtistAlbumDurationL(
       
  1053     TInt aArtistId,
       
  1054     TInt aAlbumId)
       
  1055     {
       
  1056     MPX_FUNC("CMPXDbHandler::GetArtistAlbumDurationL");
       
  1057     return iDbMusic->ArtistAlbumDurationL(aArtistId, aAlbumId);
       
  1058     }
       
  1059 
       
  1060 // ----------------------------------------------------------------------------
       
  1061 //  Get the duration for a composer
       
  1062 // ----------------------------------------------------------------------------
       
  1063 //
       
  1064 TInt CMPXDbHandler::GetComposerDurationL(
       
  1065     TInt aComposerId)
       
  1066     {
       
  1067     MPX_FUNC("CMPXDbHandler::GetComposerDurationL");
       
  1068     return iDbMusic->ComposerDurationL(aComposerId);
       
  1069     }
       
  1070 
       
  1071 // ----------------------------------------------------------------------------
       
  1072 //  Get the duration for a genre
       
  1073 // ----------------------------------------------------------------------------
       
  1074 //
       
  1075 TInt CMPXDbHandler::GetGenreDurationL(
       
  1076     TInt aGenreId)
       
  1077     {
       
  1078     MPX_FUNC("CMPXDbHandler::GetGenreDurationL");
       
  1079     return iDbMusic->GenreDurationL(aGenreId);
       
  1080     }
       
  1081 
       
  1082 // ----------------------------------------------------------------------------
       
  1083 //  Get the duration for a user playlist
       
  1084 // ----------------------------------------------------------------------------
       
  1085 //
       
  1086 TInt CMPXDbHandler::GetUserPlaylistDurationL(
       
  1087     TInt aPlaylistId)
       
  1088     {
       
  1089     MPX_FUNC("CMPXDbHandler::GetUserPlaylistDurationL");
       
  1090 
       
  1091     RArray<TMPXAttribute> attributes;
       
  1092     CleanupClosePushL(attributes);
       
  1093     attributes.AppendL(KMPXMediaGeneralId);
       
  1094     attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration));
       
  1095 
       
  1096     CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
       
  1097     CleanupStack::PushL(mediaArray);
       
  1098 
       
  1099     GetPlaylistSongsL(aPlaylistId, attributes.Array(), *mediaArray);
       
  1100 
       
  1101     TInt duration(0);
       
  1102     TInt count(mediaArray->Count());
       
  1103     for (TInt index = 0; index < count; ++index)
       
  1104         {
       
  1105         CMPXMedia* media((*mediaArray)[index]);
       
  1106         if (media->IsSupported(KMPXMediaGeneralDuration))
       
  1107             {
       
  1108             duration += media->ValueTObjectL<TInt>(KMPXMediaGeneralDuration);
       
  1109             }
       
  1110         }
       
  1111 
       
  1112     CleanupStack::PopAndDestroy(mediaArray);
       
  1113     CleanupStack::PopAndDestroy(&attributes);
       
  1114 
       
  1115     return duration;
       
  1116     }
       
  1117 
       
  1118 // ----------------------------------------------------------------------------
       
  1119 //  Get the duration for a playlist
       
  1120 // ----------------------------------------------------------------------------
       
  1121 //
       
  1122 TInt CMPXDbHandler::GetPlaylistDurationL(
       
  1123     TInt aPlaylistId)
       
  1124     {
       
  1125     MPX_FUNC("CMPXDbHandler::GetPlaylistDurationL");
       
  1126 
       
  1127     TInt duration(0);
       
  1128 
       
  1129     if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist))
       
  1130         {
       
  1131         duration = iDbMusic->RecentlyPlayedDurationL();
       
  1132         }
       
  1133     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist))
       
  1134         {
       
  1135         duration = iDbMusic->MostPlayedDurationL();
       
  1136         }
       
  1137     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyAddedPlaylist))
       
  1138         {
       
  1139         duration = iDbMusic->RecentlyAddedDurationL();
       
  1140         }
       
  1141     else
       
  1142         {
       
  1143         duration = GetUserPlaylistDurationL(aPlaylistId);
       
  1144         }
       
  1145 
       
  1146     return duration;
       
  1147     }
       
  1148 
       
  1149 // ----------------------------------------------------------------------------
       
  1150 // Find the number of items of a specified type
       
  1151 // ----------------------------------------------------------------------------
       
  1152 //
       
  1153 TInt CMPXDbHandler::NumberOfItemsL(
       
  1154     TMPXGeneralCategory aCategory)
       
  1155     {
       
  1156     MPX_FUNC("CMPXDbHandler::NumberOfItemsL");
       
  1157 
       
  1158     TInt count(0);
       
  1159     switch(aCategory)
       
  1160         {
       
  1161         case EMPXSong:
       
  1162             {
       
  1163             count = iDbMusic->CountL();
       
  1164             break;
       
  1165             }
       
  1166         case EMPXPlaylist:
       
  1167             {
       
  1168             // return the total number of playlists, including the system ones
       
  1169             count = iDbPlaylist->CountL() + EMPXAutoPlaylistCount;
       
  1170             break;
       
  1171             }
       
  1172         default:
       
  1173             {
       
  1174             count = DbCategoryL(aCategory)->CountL();
       
  1175             break;
       
  1176             }
       
  1177         }
       
  1178 
       
  1179     return count;
       
  1180     }
       
  1181 
       
  1182 // ----------------------------------------------------------------------------
       
  1183 // CMPXDbHandler::FindAllLC
       
  1184 // ----------------------------------------------------------------------------
       
  1185 //
       
  1186 CMPXMedia* CMPXDbHandler::FindAllLC(
       
  1187     const CMPXMedia& aCriteria,
       
  1188     const TArray<TMPXAttribute>& aAttrs)
       
  1189     {
       
  1190     MPX_FUNC("CMPXDbHandler::FindAllLC");
       
  1191 
       
  1192     // leave if the given media doesn't contain the following attributes
       
  1193     if (!aCriteria.IsSupported(KMPXMediaGeneralType) ||
       
  1194         !aCriteria.IsSupported(KMPXMediaGeneralCategory))
       
  1195         {
       
  1196         User::Leave(KErrArgument);
       
  1197         }
       
  1198 
       
  1199     RArray<TInt> supportedIds;
       
  1200     CleanupClosePushL(supportedIds);
       
  1201     supportedIds.AppendL(KMPXMediaIdContainer);
       
  1202     MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
       
  1203 
       
  1204     CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
       
  1205     CleanupStack::PopAndDestroy(&supportedIds);
       
  1206     CleanupStack::PushL(entries);
       
  1207 
       
  1208     CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  1209     CleanupStack::PushL(array);
       
  1210 
       
  1211     FindAllL(aCriteria, aAttrs, array);
       
  1212 
       
  1213     entries->SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXGroup);
       
  1214     entries->SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory,
       
  1215         aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory));
       
  1216     entries->SetCObjectValueL(KMPXMediaArrayContents, array);
       
  1217     entries->SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  1218 
       
  1219     CleanupStack::PopAndDestroy(array);
       
  1220     return entries;
       
  1221     }
       
  1222 
       
  1223 // ----------------------------------------------------------------------------
       
  1224 // Set the last refreshed time into the collection
       
  1225 // ----------------------------------------------------------------------------
       
  1226 //
       
  1227 void CMPXDbHandler::SetLastRefreshedTimeL(
       
  1228     TTime aTime)
       
  1229     {
       
  1230     MPX_FUNC("CMPXDbHandler::SetLastRefreshedTimeL");
       
  1231 
       
  1232     BeginTransactionL();
       
  1233     MPX_TRAPD(err, iDbAuxiliary->SetLastRefreshedTimeL(aTime));
       
  1234     EndTransactionL(err);
       
  1235     }
       
  1236 
       
  1237 // ----------------------------------------------------------------------------
       
  1238 // Get the last refreshed time from the collection
       
  1239 // ----------------------------------------------------------------------------
       
  1240 //
       
  1241 TTime CMPXDbHandler::GetLastRefreshedTimeL()
       
  1242     {
       
  1243     MPX_FUNC("CMPXDbHandler::GetLastRefreshedTimeL");
       
  1244     return iDbAuxiliary->LastRefreshedTimeL();
       
  1245     }
       
  1246 
       
  1247 // ----------------------------------------------------------------------------
       
  1248 // Set the db corrupted state for all drives
       
  1249 // ----------------------------------------------------------------------------
       
  1250 //
       
  1251 void CMPXDbHandler::SetDBCorruptedL(
       
  1252     TBool aCorrupted)
       
  1253     {
       
  1254     MPX_FUNC("CMPXDbHandler::SetDBCorruptedL");
       
  1255 
       
  1256     BeginTransactionL();
       
  1257     MPX_TRAPD(err, iDbAuxiliary->SetDBCorruptedL(aCorrupted));
       
  1258     EndTransactionL(err);
       
  1259     }
       
  1260 
       
  1261 // ----------------------------------------------------------------------------
       
  1262 // Gets the db corrupted state for all drives
       
  1263 // ----------------------------------------------------------------------------
       
  1264 //
       
  1265 TBool CMPXDbHandler::IsDBCorruptedL()
       
  1266     {
       
  1267     MPX_FUNC("CMPXDbHandler::IsDBCorruptedL");
       
  1268     return iDbAuxiliary->DBCorruptedL();
       
  1269     }
       
  1270 
       
  1271 // ----------------------------------------------------------------------------
       
  1272 // Have the databases been created?
       
  1273 // ----------------------------------------------------------------------------
       
  1274 //
       
  1275 TBool CMPXDbHandler::DatabaseCreated()
       
  1276     {
       
  1277     MPX_FUNC("CMPXDbHandler::DatabaseCreatedL");
       
  1278 
       
  1279     TBool AuxilaryDbIsRefreshed(EFalse);
       
  1280     TRAP_IGNORE(AuxilaryDbIsRefreshed = iDbAuxiliary->IsRefreshedL());
       
  1281     // If none of the databases were available, ie out of disk we return EFalse
       
  1282     return iDbManager->IsInitialized() && AuxilaryDbIsRefreshed;
       
  1283     }
       
  1284 
       
  1285 // ----------------------------------------------------------------------------
       
  1286 // Open a database
       
  1287 // ----------------------------------------------------------------------------
       
  1288 //
       
  1289 void CMPXDbHandler::OpenDatabaseL(
       
  1290     TInt aDrive)
       
  1291     {
       
  1292     MPX_FUNC("CMPXDbHandler::OpenDatabaseL");
       
  1293     MPX_DEBUG2( "CMPXDbHandler::OpenDatabaseL: %i", aDrive);
       
  1294     iDbManager->OpenDatabaseL(aDrive);
       
  1295 
       
  1296     // Verify the volume ID after a remount event
       
  1297     VerifyVolumeIdL();
       
  1298     }
       
  1299 
       
  1300 // ----------------------------------------------------------------------------
       
  1301 // Close a database
       
  1302 // ----------------------------------------------------------------------------
       
  1303 //
       
  1304 void CMPXDbHandler::CloseDatabaseL(
       
  1305     TInt aDrive)
       
  1306     {
       
  1307     MPX_FUNC("CMPXDbHandler::CloseDatabaseL");
       
  1308     MPX_DEBUG2( "CMPXDbHandler::CloseDatabaseL drive: %i", aDrive );
       
  1309     iDbManager->CloseDatabaseL(aDrive);
       
  1310     }
       
  1311 
       
  1312 // ----------------------------------------------------------------------------
       
  1313 // Re-create all databases
       
  1314 // ----------------------------------------------------------------------------
       
  1315 //
       
  1316 void CMPXDbHandler::ReCreateDatabasesL()
       
  1317     {
       
  1318     MPX_FUNC("CMPXDbHandler::ReCreateDatabasesL");
       
  1319     iDbManager->RecreateAllDatabasesL();
       
  1320     }
       
  1321 
       
  1322 // ----------------------------------------------------------------------------
       
  1323 // Set handler refresh status
       
  1324 // ----------------------------------------------------------------------------
       
  1325 //
       
  1326 void CMPXDbHandler::RefreshStartL()
       
  1327     {
       
  1328     MPX_FUNC("CMPXDbHandler::RefreshStartL");
       
  1329 
       
  1330     iOutOfDisk = EFalse;
       
  1331     // Re-open databases
       
  1332     // This is needed for the case where we were OOD before, but user
       
  1333     // has cleared some space but now try to refresh
       
  1334     MPX_TRAPD(err, iDbManager->InitDatabasesL(iDbDrives));
       
  1335     iCollectionOpen = ETrue;
       
  1336     // Update (synchronize) music basic table if it's not
       
  1337     // in sync with music table
       
  1338     if(iSynchronizeBasicTable)
       
  1339         {
       
  1340         iDbMusic->RefreshEndL();
       
  1341         }
       
  1342     iSynchronizeBasicTable = ETrue;
       
  1343 
       
  1344     if(err == KErrDiskFull)
       
  1345         {
       
  1346             iOutOfDisk = ETrue;
       
  1347         }
       
  1348 
       
  1349     if(!iOutOfDisk)
       
  1350     {
       
  1351         MPX_TRAP(err,CheckDiskSpaceOnDrivesL());
       
  1352 
       
  1353         if(err == KErrDiskFull)
       
  1354             {
       
  1355             iOutOfDisk = ETrue;
       
  1356             }
       
  1357     }
       
  1358     
       
  1359 #ifdef __RAMDISK_PERF_ENABLE
       
  1360 	iDbManager->CopyDBsToRamL();
       
  1361 #endif //__RAMDISK_PERF_ENABLE
       
  1362     iDbMusic->RefreshStartL();
       
  1363 
       
  1364     BeginTransactionL();
       
  1365     iRefresh = ETrue;
       
  1366     }
       
  1367 
       
  1368 // ----------------------------------------------------------------------------
       
  1369 // Re-set handler refresh status
       
  1370 // ----------------------------------------------------------------------------
       
  1371 //
       
  1372 void CMPXDbHandler::RefreshEndL()
       
  1373     {
       
  1374     MPX_FUNC("CMPXDbHandler::RefreshEndL");
       
  1375     iRefresh = EFalse;
       
  1376     EndTransactionL(KErrNone);
       
  1377     if (!iOutOfDisk)
       
  1378         {
       
  1379         // Write last refreshed time as current time
       
  1380         // This also sets corrupt = 0
       
  1381         TTime curTime;
       
  1382         curTime.HomeTime();
       
  1383         SetLastRefreshedTimeL(curTime);
       
  1384         }
       
  1385     iDbMusic->RefreshEndL();
       
  1386     //Update of music basic table fails when the collection is not open
       
  1387     //Next time the collection is opened the music basic table must be updated
       
  1388     if (iCollectionOpen )
       
  1389         {
       
  1390         iSynchronizeBasicTable = EFalse;
       
  1391         }
       
  1392 
       
  1393 #ifdef __RAMDISK_PERF_ENABLE
       
  1394     iDbManager->CopyDBsFromRamL();
       
  1395 #endif //__RAMDISK_PERF_ENABLE
       
  1396     }
       
  1397 
       
  1398 // ----------------------------------------------------------------------------
       
  1399 // Notification of Mtp status change
       
  1400 // ----------------------------------------------------------------------------
       
  1401 //
       
  1402 void CMPXDbHandler::MtpStartL()
       
  1403     {
       
  1404     MPX_DEBUG1("-->CMPXDbHandler::MtpStartL");
       
  1405     iMtpInUse = ETrue;
       
  1406     iOpOnDbCount = 0;
       
  1407 
       
  1408 #ifdef __RAMDISK_PERF_ENABLE
       
  1409 	TRAPD(err, iDbManager->CopyDBsToRamL(iMtpInUse));
       
  1410 	if ( err != KErrNone )
       
  1411 	    {
       
  1412         MPX_DEBUG2("CMPXDbHandler::MtpStartL error=%d", err);
       
  1413 	    }
       
  1414 #endif //__RAMDISK_PERF_ENABLE
       
  1415 
       
  1416     iDbManager->BeginL();
       
  1417     MPX_DEBUG1("<--CMPXDbHandler::MtpStartL");
       
  1418     }
       
  1419 
       
  1420 // ----------------------------------------------------------------------------
       
  1421 // Notification of Mtp status change
       
  1422 // ----------------------------------------------------------------------------
       
  1423 //
       
  1424 void CMPXDbHandler::MtpEndL()
       
  1425     {
       
  1426     MPX_DEBUG1("-->CMPXDbHandler::MtpEndL");
       
  1427     iMtpInUse = EFalse;
       
  1428     iOpOnDbCount = 0;
       
  1429     iDbManager->CommitL();
       
  1430 
       
  1431 #ifdef __RAMDISK_PERF_ENABLE
       
  1432     TRAPD(err, iDbManager->CopyDBsFromRamL());
       
  1433 	if ( err != KErrNone )
       
  1434 	    {
       
  1435         MPX_DEBUG2("CMPXDbHandler::MtpEndL error=%d", err);
       
  1436 	    }
       
  1437 #endif //__RAMDISK_PERF_ENABLE
       
  1438     
       
  1439     MPX_DEBUG1("<--CMPXDbHandler::MtpEndL");
       
  1440     }
       
  1441 
       
  1442 // ----------------------------------------------------------------------------
       
  1443 // Get all records count for music
       
  1444 // ----------------------------------------------------------------------------
       
  1445 //
       
  1446 TUint CMPXDbHandler::GetMusicCountL(TInt aDrive)
       
  1447     {
       
  1448     MPX_FUNC("CMPXDbHandler::GetMusicCountL");
       
  1449     TUint total(0);
       
  1450 
       
  1451     //music
       
  1452     total += iDbMusic->GetDriveTrackCountL(aDrive);
       
  1453 
       
  1454     return total;
       
  1455     }
       
  1456 
       
  1457 // ----------------------------------------------------------------------------
       
  1458 // Get all records count for playlists
       
  1459 // ----------------------------------------------------------------------------
       
  1460 //
       
  1461 TUint CMPXDbHandler::GetPlaylistCountL(TInt aDrive)
       
  1462     {
       
  1463     MPX_FUNC("CMPXDbHandler::GetPlaylistCountL");
       
  1464     TUint total(0);
       
  1465 
       
  1466     //playlist
       
  1467     total += iDbPlaylist->GetDrivePlaylistCountL(aDrive);
       
  1468 
       
  1469     return total;
       
  1470     }
       
  1471 
       
  1472 // ----------------------------------------------------------------------------
       
  1473 // Get all records count for music and playlists
       
  1474 // ----------------------------------------------------------------------------
       
  1475 //
       
  1476 TUint CMPXDbHandler::GetTotalCountL(TInt aDrive)
       
  1477     {
       
  1478     MPX_FUNC("CMPXDbHandler::GetTotalCountL");
       
  1479     TUint total(0);
       
  1480 
       
  1481     //music
       
  1482     total += iDbMusic->GetDriveTrackCountL(aDrive);
       
  1483     //playlist
       
  1484     total += iDbPlaylist->GetDrivePlaylistCountL(aDrive);
       
  1485 
       
  1486     return total;
       
  1487     }
       
  1488 
       
  1489 // ----------------------------------------------------------------------------
       
  1490 // Get all records count for music and playlists
       
  1491 // ----------------------------------------------------------------------------
       
  1492 //
       
  1493 void CMPXDbHandler::GetMusicUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
       
  1494                                       CDesCArray& aUriArr, TInt& aLastID)
       
  1495     {
       
  1496     MPX_FUNC("CMPXDbHandler::GetMusicUriArrayL");
       
  1497 
       
  1498     iDbMusic->GetMusicUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
       
  1499     }
       
  1500 
       
  1501 // ----------------------------------------------------------------------------
       
  1502 // Get all records count for music and playlists
       
  1503 // ----------------------------------------------------------------------------
       
  1504 //
       
  1505 void CMPXDbHandler::GetPlaylistUriArrayL(TInt aDrive, TInt aFromID, TInt aRecords,
       
  1506                                          CDesCArray& aUriArr, TInt& aLastID)
       
  1507     {
       
  1508     MPX_FUNC("CMPXDbHandler::GetPlaylistUriArrayL");
       
  1509 
       
  1510     iDbPlaylist->GetPlaylistUriArrayL(aDrive,aFromID,aRecords,aUriArr,aLastID);
       
  1511     }
       
  1512 
       
  1513 // ----------------------------------------------------------------------------
       
  1514 // Starts a transaction on all databases
       
  1515 // ----------------------------------------------------------------------------
       
  1516 //
       
  1517 void CMPXDbHandler::BeginTransactionL()
       
  1518     {
       
  1519     MPX_FUNC("CMPXDbHandler::BeginTransactionL");
       
  1520 
       
  1521 #ifdef __RAMDISK_PERF_ENABLE
       
  1522     // EnsureRamSpaceL will copy dbs from ram if ram space is low or dbs exceeded
       
  1523     // max space.
       
  1524 	TRAPD(err, iDbManager->EnsureRamSpaceL());
       
  1525 	if (err)
       
  1526 		{
       
  1527 		//error but continue
       
  1528 		}
       
  1529 #endif //__RAMDISK_PERF_ENABLE
       
  1530 
       
  1531     if(!iMtpInUse)
       
  1532         {
       
  1533         iDbManager->BeginL();
       
  1534         }
       
  1535     }
       
  1536 
       
  1537 // ----------------------------------------------------------------------------
       
  1538 // Ends a transaction on all databases
       
  1539 // ----------------------------------------------------------------------------
       
  1540 //
       
  1541 void CMPXDbHandler::EndTransactionL(
       
  1542     TInt aError)
       
  1543     {
       
  1544     MPX_FUNC("CMPXDbHandler::EndTransactionL");
       
  1545 
       
  1546     if(iMtpInUse)
       
  1547         {
       
  1548         if (aError)
       
  1549             {
       
  1550             iOpOnDbCount = 0;
       
  1551             iDbManager->RollbackL();
       
  1552             User::Leave(aError);
       
  1553             }
       
  1554         
       
  1555         if(iOpOnDbCount >= KMaxOpInTransaction)
       
  1556             {
       
  1557             MPX_DEBUG2("CMPXDbHandler::EndTransactionL - %d>KMaxOpInTransaction Commiting",iOpOnDbCount);
       
  1558             iOpOnDbCount = 0;
       
  1559             iDbManager->CommitL();
       
  1560             iDbManager->BeginL();
       
  1561             }        
       
  1562         }
       
  1563     else
       
  1564         {
       
  1565         if (aError)
       
  1566             {
       
  1567             MPX_DEBUG2("CMPXDbHandler::EndTransactionL - Rollback [%d]", aError);
       
  1568 
       
  1569             iDbManager->RollbackL();
       
  1570             
       
  1571             // KSqlDbCorrupted indicates DB corrupted, need to recreate.
       
  1572             if ( aError != KSqlDbCorrupted )
       
  1573                 {
       
  1574                 User::Leave(aError);
       
  1575                 }
       
  1576             }
       
  1577         else
       
  1578             {
       
  1579             iDbManager->CommitL();
       
  1580             }
       
  1581         }
       
  1582     }
       
  1583 
       
  1584 // ----------------------------------------------------------------------------
       
  1585 // Checks if the database is currently in a transaction
       
  1586 // ----------------------------------------------------------------------------
       
  1587 //
       
  1588 TBool CMPXDbHandler::InTransaction()
       
  1589     {
       
  1590     MPX_FUNC("CMPXDbHandler::InTransaction");
       
  1591     return iDbManager->InTransaction();
       
  1592     }
       
  1593 
       
  1594 // ----------------------------------------------------------------------------
       
  1595 // Notifies the handler that the collection will be closed.
       
  1596 // It is called before closing the collection.
       
  1597 // ----------------------------------------------------------------------------
       
  1598 //
       
  1599 void CMPXDbHandler::PreCloseCollectionL()
       
  1600     {
       
  1601     MPX_FUNC("CMPXDbHandler::PreCloseCollectionL");
       
  1602     // Complete pending transaction and set the latest refresh time
       
  1603     // before closing the databases if collection close event occurs
       
  1604     // before the end of the refresh operation
       
  1605     if(iRefresh)
       
  1606         {
       
  1607         EndTransactionL(KErrNone);
       
  1608         if (!iOutOfDisk)
       
  1609             {
       
  1610             // Write last refreshed time as current time
       
  1611             // This also sets corrupt = 0
       
  1612             TTime curTime;
       
  1613             curTime.HomeTime();
       
  1614             SetLastRefreshedTimeL(curTime);
       
  1615             }
       
  1616         }
       
  1617     }
       
  1618 
       
  1619 // ----------------------------------------------------------------------------
       
  1620 // Notifies the handler that the collection was closed.
       
  1621 // ----------------------------------------------------------------------------
       
  1622 //
       
  1623 void CMPXDbHandler::CollectionClosed()
       
  1624     {
       
  1625     MPX_FUNC("CMPXDbHandler::CollectionClosed");
       
  1626 
       
  1627     iCollectionOpen = EFalse;
       
  1628     }
       
  1629 
       
  1630 // ----------------------------------------------------------------------------
       
  1631 //Notifies the handler that the collection was opened.
       
  1632 // ----------------------------------------------------------------------------
       
  1633 //
       
  1634 void CMPXDbHandler::CollectionOpenedL()
       
  1635     {
       
  1636     MPX_FUNC("CMPXDbHandler::CollectionOpened");
       
  1637 
       
  1638     iCollectionOpen = ETrue;
       
  1639     // Update (synchronize) music basic table if it's not
       
  1640     // in sync with music table
       
  1641     if(iSynchronizeBasicTable)
       
  1642         {
       
  1643         iDbMusic->RefreshEndL();
       
  1644         iSynchronizeBasicTable = EFalse;
       
  1645         }
       
  1646     }
       
  1647 
       
  1648 // ----------------------------------------------------------------------------
       
  1649 // Add song to collection
       
  1650 // ----------------------------------------------------------------------------
       
  1651 //
       
  1652 TUint32 CMPXDbHandler::DoAddSongL(
       
  1653     const CMPXMedia& aMedia,
       
  1654     CMPXMessageArray* aMessageArray)
       
  1655     {
       
  1656     MPX_FUNC("CMPXDbHandler::DoAddSongL");
       
  1657 
       
  1658     if (!aMedia.IsSupported(KMPXMediaGeneralUri))
       
  1659         {
       
  1660         User::Leave(KErrArgument);
       
  1661         }
       
  1662 
       
  1663     // add the song to the Music table
       
  1664     TDriveUnit drive(aMedia.ValueText(KMPXMediaGeneralUri));
       
  1665     TUint32 songId(iDbMusic->AddSongL(aMedia, drive,
       
  1666                                       iRefresh?NULL:aMessageArray));
       
  1667 
       
  1668     // update the playlist tables
       
  1669     // make sure the song db flags are reset and not just updated
       
  1670     iDbPlaylist->UpdateSongL(aMedia, ETrue);
       
  1671     
       
  1672     if(iMtpInUse)
       
  1673         {
       
  1674         ++iOpOnDbCount;
       
  1675         }
       
  1676 
       
  1677     return songId;
       
  1678     }
       
  1679 
       
  1680 // ----------------------------------------------------------------------------
       
  1681 // Add playlist to collection
       
  1682 // ----------------------------------------------------------------------------
       
  1683 //
       
  1684 TUint32 CMPXDbHandler::DoAddPlaylistL(
       
  1685     const CMPXMedia& aMedia)
       
  1686     {
       
  1687     MPX_FUNC("CMPXDbHandler::DoAddPlaylistL");
       
  1688 
       
  1689     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1690     CleanupStack::PushL(media);
       
  1691 
       
  1692     const TDesC& playlistUri = media->ValueText(KMPXMediaGeneralUri);
       
  1693 
       
  1694     //
       
  1695     // client has asked to create a virtual playlist if file name is not specified
       
  1696     // in the URI. In this case, generate URI for virtual playlist specified as
       
  1697     // follows:
       
  1698     //          <dir path>\timestamp.vir
       
  1699     //
       
  1700     TParsePtrC parser(playlistUri);
       
  1701 
       
  1702     if (!parser.NameOrExtPresent() ||
       
  1703         parser.IsNameWild() ||
       
  1704         parser.IsExtWild())
       
  1705         {
       
  1706         HBufC* newUri = HBufC::NewLC(parser.DriveAndPath().Length() + KMCMaxTextLen +
       
  1707             KMPXVirtualPlaylistExt().Length());
       
  1708 
       
  1709         TPtr ptr = newUri->Des();
       
  1710         ptr.Append(parser.DriveAndPath());
       
  1711         TTime time;
       
  1712         time.HomeTime();
       
  1713         ptr.AppendNum(time.Int64());
       
  1714         ptr.Append(KMPXVirtualPlaylistExt);
       
  1715 
       
  1716         // overwrite the old uri with the new one with full path and playlist
       
  1717         // playlist filename
       
  1718         media->SetTextValueL(KMPXMediaGeneralUri, *newUri);
       
  1719 
       
  1720         CleanupStack::PopAndDestroy(newUri);
       
  1721 
       
  1722         // set DbFlags to indicate that this is a virtual playlist
       
  1723         media->SetTObjectValueL<TUint>(KMPXMediaGeneralFlags,
       
  1724             KMPXMediaGeneralFlagsSetOrUnsetBit | KMPXMediaGeneralFlagsIsVirtual);
       
  1725         }
       
  1726 
       
  1727     // complete the song attributes from the music table
       
  1728     UpdatePlaylistSongInfoL(*media);
       
  1729 
       
  1730     // add playlist to the database
       
  1731     TUint32 playlistId = iDbPlaylist->AddPlaylistL(*media);
       
  1732 
       
  1733     CleanupStack::PopAndDestroy(media);
       
  1734     return playlistId;
       
  1735     }
       
  1736 
       
  1737 // ----------------------------------------------------------------------------
       
  1738 // Add song to playlist
       
  1739 // ----------------------------------------------------------------------------
       
  1740 //
       
  1741 TUint32 CMPXDbHandler::DoAddSongToPlaylistL(
       
  1742     const CMPXMedia& aMedia)
       
  1743     {
       
  1744     MPX_FUNC("CMPXDbHandler::DoAddSongToPlaylistL");
       
  1745 
       
  1746     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1747     CleanupStack::PushL(media);
       
  1748 
       
  1749     // complete the song attributes from the music table
       
  1750     UpdatePlaylistSongInfoL(*media);
       
  1751 
       
  1752     // add the songs to the playlist
       
  1753     TUint32 playlistId((media->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2);
       
  1754 
       
  1755     CMPXMediaArray* ary( aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents) );
       
  1756     User::LeaveIfNull( ary );
       
  1757     iDbPlaylist->AddSongsL(playlistId,*ary);
       
  1758 
       
  1759     CleanupStack::PopAndDestroy(media);
       
  1760     return playlistId;
       
  1761     }
       
  1762 
       
  1763 // ----------------------------------------------------------------------------
       
  1764 // Update a song in the collection
       
  1765 // ----------------------------------------------------------------------------
       
  1766 //
       
  1767 CMPXDbActiveTask::TChangeVisibility CMPXDbHandler::DoUpdateSongL(
       
  1768     const CMPXMedia& aMedia,
       
  1769     CMPXMessageArray& aItemChangedMessages)
       
  1770     {
       
  1771     MPX_FUNC("CMPXDbHandler::DoUpdateSongL");
       
  1772 
       
  1773     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
  1774 
       
  1775     TUint32 songId(0);
       
  1776 
       
  1777     if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  1778         {
       
  1779         songId = (aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  1780         }
       
  1781     if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  1782         {
       
  1783         const TDesC& uri = aMedia.ValueText(KMPXMediaGeneralUri);
       
  1784         songId = MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, uri, EFalse);
       
  1785         }
       
  1786     if (!songId)
       
  1787         {
       
  1788         User::Leave(KErrNotSupported);
       
  1789         }
       
  1790 
       
  1791     // Update the Music table
       
  1792     TRAPD(err, visibleChange = iDbMusic->UpdateSongL(songId, aMedia, aItemChangedMessages));
       
  1793 
       
  1794     // do not leave if song is not found in Music table
       
  1795     // leave for other errors such as disk full
       
  1796     if(err != KErrNone && err != KErrNotFound)
       
  1797         {
       
  1798         User::Leave(err);
       
  1799         }
       
  1800 
       
  1801     // Update the Playlist table
       
  1802     TBool visible = EFalse;
       
  1803 
       
  1804     TRAP( err, visible = iDbPlaylist->UpdateSongL(aMedia, EFalse, &aItemChangedMessages));
       
  1805 
       
  1806     // do not leave if song is not found in Playlist table
       
  1807     // leave for other errors such as disk full
       
  1808     if(err != KErrNone && err != KErrNotFound)
       
  1809         {
       
  1810         User::Leave(err);
       
  1811         }
       
  1812 
       
  1813     // make it visible if either table is updated
       
  1814     if (visible)
       
  1815         {
       
  1816         visibleChange = CMPXDbActiveTask::EAllVisible;
       
  1817         }
       
  1818     if ( aMedia.ValueTObjectL<TInt>( KMPXMediaMusicAlbumArtChanged )== 1 )
       
  1819         {
       
  1820         ( const_cast<CMPXMedia*>( &aMedia ) 
       
  1821         		)->SetTObjectValueL<TInt>( KMPXMediaMusicAlbumArtChanged, 0 );
       
  1822         }
       
  1823 
       
  1824     return visibleChange;
       
  1825     }
       
  1826 
       
  1827 // ----------------------------------------------------------------------------
       
  1828 // Update a playlist in the collection
       
  1829 // ----------------------------------------------------------------------------
       
  1830 //
       
  1831 void CMPXDbHandler::DoUpdatePlaylistL(
       
  1832     const CMPXMedia& aMedia,
       
  1833     CMPXMessageArray& aMessageArray)
       
  1834     {
       
  1835     MPX_FUNC("CMPXDbHandler::DoUpdatePlaylistL");
       
  1836 
       
  1837     TUint32 playlistId(0);
       
  1838     TInt drive(0);
       
  1839 
       
  1840     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1841     CleanupStack::PushL(media);
       
  1842 
       
  1843 
       
  1844     ProcessPlaylistMediaL(*media, playlistId, drive);
       
  1845 
       
  1846     CMPXMessage* m1 = CMPXMessage::NewL();
       
  1847     CleanupStack::PushL(m1);
       
  1848     CMPXMessage* m2 = CMPXMessage::NewL();
       
  1849     CleanupStack::PushL(m2);
       
  1850 
       
  1851     // send 2 messages to notify the playlist change & to refresh the display (update playlist name)
       
  1852     MPXDbCommonUtil::FillItemChangedMessageL(*m1, playlistId, EMPXItemModified,
       
  1853             EMPXPlaylist, KDBPluginUid);
       
  1854 
       
  1855     MPXDbCommonUtil::FillItemChangedMessageL(*m2, EBrowsePlaylist, EMPXItemModified,
       
  1856                 EMPXPlaylist, KDBPluginUid);
       
  1857 
       
  1858     iDbPlaylist->UpdatePlaylistL(*media, *m1, drive);
       
  1859 
       
  1860     aMessageArray.AppendL(*m1);
       
  1861     aMessageArray.AppendL(*m2);
       
  1862 
       
  1863 
       
  1864     CleanupStack::PopAndDestroy(m2);
       
  1865     CleanupStack::PopAndDestroy(m1);
       
  1866     CleanupStack::PopAndDestroy(media);
       
  1867     }
       
  1868 
       
  1869 // ----------------------------------------------------------------------------
       
  1870 // Update a playlist in the collection
       
  1871 // ----------------------------------------------------------------------------
       
  1872 //
       
  1873 void CMPXDbHandler::DoUpdatePlaylistSongsL(
       
  1874     const CMPXMedia& aMedia,
       
  1875     CMPXMessage& aMessage)
       
  1876     {
       
  1877     MPX_FUNC("CMPXDbHandler::DoUpdatePlaylistSongsL");
       
  1878 
       
  1879     CMPXMedia* media = CMPXMedia::NewL(aMedia);
       
  1880     CleanupStack::PushL(media);
       
  1881 
       
  1882     TUint32 playlistId(0);
       
  1883     TInt drive(0);
       
  1884 
       
  1885     // get the playlist ID and drive ID
       
  1886     ProcessPlaylistMediaL(*media, playlistId, drive);
       
  1887     MPXDbCommonUtil::FillItemChangedMessageL(aMessage, playlistId, EMPXItemModified,
       
  1888         EMPXPlaylist, KDBPluginUid);
       
  1889 
       
  1890     // complete the song attributes from the Music table
       
  1891     UpdatePlaylistSongInfoL(*media);
       
  1892 
       
  1893     // delete existing songs for the playlist first
       
  1894     iDbPlaylist->Songs().DeleteSongsL(playlistId, drive);
       
  1895 
       
  1896     // add new songs to the playlist
       
  1897     CMPXMediaArray* ary( media->Value<CMPXMediaArray>(KMPXMediaArrayContents ) );
       
  1898     User::LeaveIfNull( ary );
       
  1899     iDbPlaylist->AddSongsL(playlistId, *ary);
       
  1900 
       
  1901     CleanupStack::PopAndDestroy(media);
       
  1902     }
       
  1903 
       
  1904 // ----------------------------------------------------------------------------
       
  1905 // Reorder a song in a playlist
       
  1906 // ----------------------------------------------------------------------------
       
  1907 //
       
  1908 void CMPXDbHandler::DoReorderPlaylistL(
       
  1909     const TMPXItemId& aPlaylistId,
       
  1910     const TMPXItemId& aSongId,
       
  1911     TUint aOriginalOrdinal,
       
  1912     TUint aNewOrdinal,
       
  1913     CMPXMessage& aMessage)
       
  1914     {
       
  1915     MPX_DEBUG1("-->CMPXDbHandler::DoReorderPlaylistL()");
       
  1916 
       
  1917     if (aOriginalOrdinal != aNewOrdinal)
       
  1918         {
       
  1919         iDbPlaylist->Songs().ReorderSongL(aPlaylistId, aSongId, aOriginalOrdinal, aNewOrdinal);
       
  1920 
       
  1921         MPXDbCommonUtil::FillItemChangedMessageL(aMessage, aPlaylistId.iId2, EMPXItemModified,
       
  1922             EMPXPlaylist, KDBPluginUid);
       
  1923         }
       
  1924 
       
  1925     MPX_DEBUG1("<--CMPXDbHandler::DoReorderPlaylistL()");
       
  1926     }
       
  1927 
       
  1928 // ----------------------------------------------------------------------------
       
  1929 // Delete a song from collection
       
  1930 // The function notifies collection model to perform deletion
       
  1931 // ----------------------------------------------------------------------------
       
  1932 //
       
  1933 void CMPXDbHandler::DoRemoveSongL(
       
  1934     TUint32 aSongId,
       
  1935     CDesCArray& aUriArray,
       
  1936     CMPXMessageArray& aItemChangedMessages,
       
  1937     TBool aDeleteRecord)
       
  1938     {
       
  1939     MPX_FUNC("CMPXDbHandler::DoRemoveSongL");
       
  1940 
       
  1941     // Get the song drive
       
  1942     TUint32 artistID(0);
       
  1943     TUint32 albumID(0);
       
  1944     TUint32 genreID(0);
       
  1945     TUint32 composerID(0);
       
  1946     TInt drive(0);
       
  1947 
       
  1948     // Get information from the Music table first
       
  1949     HBufC* uri = iDbMusic->GetSongInfoL(aSongId, artistID, albumID, genreID, composerID, drive);
       
  1950 
       
  1951     // add the URI to the return array
       
  1952     CleanupStack::PushL(uri);
       
  1953     aUriArray.AppendL(*uri);
       
  1954     CleanupStack::PopAndDestroy(uri);
       
  1955 
       
  1956     // Update the category records
       
  1957     TBool categoryExist( EFalse );
       
  1958     iDbArtist->DecrementSongsForCategoryL(artistID, drive, &aItemChangedMessages, categoryExist);
       
  1959     iDbAlbum->DecrementSongsForCategoryL(albumID, drive, &aItemChangedMessages, categoryExist, artistID);
       
  1960     iDbGenre->DecrementSongsForCategoryL(genreID, drive, &aItemChangedMessages, categoryExist);
       
  1961     iDbComposer->DecrementSongsForCategoryL(composerID, drive, &aItemChangedMessages, categoryExist);
       
  1962 
       
  1963     // Update the music table
       
  1964     TBool deleteRecord(ETrue);
       
  1965 
       
  1966 #if defined (__MTP_PROTOCOL_SUPPORT)
       
  1967     // Mark the song record as deleted if the following is true; otherwise, delete the
       
  1968     // song record.
       
  1969     //
       
  1970     // A client other than MTP has initiated this song deletion (aDeleteRecord is EFalse)
       
  1971     // and MTP has turned on its cenrep key to save deleted records and current number of
       
  1972     // saved deleted records has not exceeded its maximum, KMCMaxSavedDeletedRecords.
       
  1973     //
       
  1974     // Songs are marked as deleted in order to support auto-sync. MTP will delete these
       
  1975     // marked records at the end of each session via CleanupDeletedRecordsL.
       
  1976     //
       
  1977     // For performance consideration, if the number of saved records exceeds its maximum,
       
  1978     // song record will be deleted.
       
  1979     if (!aDeleteRecord && SaveDeletedSongs())
       
  1980         {
       
  1981         TUint32 savedDeletedRecordCount(iDbAuxiliary->SaveDeletedRecordCountL());
       
  1982         MPX_DEBUG2("Current number of saved deleted record count is %d", savedDeletedRecordCount);
       
  1983 
       
  1984         if (savedDeletedRecordCount < KMCMaxSavedDeletedRecords)
       
  1985             {
       
  1986             deleteRecord = EFalse;
       
  1987             TUint32 savedDeletedDriveRecordCount(iDbAuxiliary->SaveDeletedRecordCountL(drive));
       
  1988             iDbAuxiliary->SetSaveDeletedRecordCountL(drive,++savedDeletedDriveRecordCount);
       
  1989             }
       
  1990         }
       
  1991 #endif
       
  1992 
       
  1993     // delete the song from the Music table
       
  1994     iDbMusic->DeleteSongL(aSongId, drive, deleteRecord);
       
  1995 
       
  1996     // add the item changed message
       
  1997     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aSongId, EMPXItemDeleted,
       
  1998         EMPXSong, KDBPluginUid);
       
  1999         
       
  2000 
       
  2001     if(iMtpInUse)
       
  2002         {
       
  2003         ++iOpOnDbCount;
       
  2004         }
       
  2005     }
       
  2006 
       
  2007 // ----------------------------------------------------------------------------
       
  2008 // Delete a song from playlist tables
       
  2009 // ----------------------------------------------------------------------------
       
  2010 //
       
  2011 void CMPXDbHandler::DoRemoveSongFromPlaylistL(TUint32 aSongId,CMPXMessageArray& aItemChangedMessages)
       
  2012     {
       
  2013     MPX_FUNC("CMPXDbHandler::DoRemoveSongFromPlaylistL");
       
  2014     // delete song from the playlist tables on all drives
       
  2015     iDbPlaylist->DeleteSongL(aSongId, aItemChangedMessages);
       
  2016     }
       
  2017 
       
  2018 // ----------------------------------------------------------------------------
       
  2019 // Removes a category of songs from the music collection,
       
  2020 // and its corresponding category in the lookup table
       
  2021 // ----------------------------------------------------------------------------
       
  2022 //
       
  2023 void CMPXDbHandler::DoRemoveSongsMatchingCategoryL(
       
  2024     TMPXGeneralCategory aCategory,
       
  2025     TUint32 aCategoryId,
       
  2026     CDesCArray& aUriArray,
       
  2027     CMPXMessageArray& aItemChangedMessages)
       
  2028     {
       
  2029     MPX_FUNC("CMPXDbHandler::DoRemoveSongsMatchingCategoryL");
       
  2030 
       
  2031     // get the songs for the specified category
       
  2032     CMPXMediaArray* songs = CMPXMediaArray::NewL();
       
  2033     CleanupStack::PushL(songs);
       
  2034 
       
  2035     RArray<TMPXAttribute> attributes;
       
  2036     CleanupClosePushL(attributes);
       
  2037     attributes.AppendL(KMPXMediaGeneralId);
       
  2038 
       
  2039     switch (aCategory)
       
  2040         {
       
  2041         case EMPXArtist:
       
  2042             {
       
  2043             iDbMusic->GetSongsForArtistL(aCategoryId, attributes.Array(), *songs);
       
  2044             break;
       
  2045             }
       
  2046         case EMPXAlbum:
       
  2047             {
       
  2048             iDbMusic->GetSongsForAlbumL(aCategoryId, attributes.Array(), *songs);
       
  2049             break;
       
  2050             }
       
  2051         case EMPXGenre:
       
  2052             {
       
  2053             iDbMusic->GetSongsForGenreL(aCategoryId, attributes.Array(), *songs);
       
  2054             break;
       
  2055             }
       
  2056         case EMPXComposer:
       
  2057             {
       
  2058             iDbMusic->GetSongsForComposerL(aCategoryId, attributes.Array(), *songs);
       
  2059             break;
       
  2060             }
       
  2061         default:
       
  2062             User::Leave(KErrNotSupported);
       
  2063         }
       
  2064 
       
  2065     CleanupStack::PopAndDestroy(&attributes);
       
  2066 
       
  2067     // iterate the songs and remove them one by one
       
  2068     // so records in the category tables can also be updated
       
  2069     TInt count(songs->Count());
       
  2070     for (TInt index = 0; index < count; ++index)
       
  2071         {
       
  2072         CMPXMedia* song = (*songs)[index];
       
  2073         if (song->IsSupported(KMPXMediaGeneralId))
       
  2074             {
       
  2075             DoRemoveSongL((song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2,
       
  2076                 aUriArray, aItemChangedMessages, EFalse);
       
  2077             DoRemoveSongFromPlaylistL((song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2,aItemChangedMessages);
       
  2078             }
       
  2079         }
       
  2080 
       
  2081     CleanupStack::PopAndDestroy(songs);
       
  2082     }
       
  2083 
       
  2084 // ----------------------------------------------------------------------------------------------------------
       
  2085 // Delete songs for the specified artist and album from collection
       
  2086 // ----------------------------------------------------------------------------------------------------------
       
  2087 //
       
  2088 void CMPXDbHandler::DoRemoveSongsMatchingArtistAndAlbumL(
       
  2089     TUint32 aArtistId,
       
  2090     TUint32 aAlbumId,
       
  2091     CDesCArray& aUriArray,
       
  2092     CMPXMessageArray& aItemChangedMessages)
       
  2093     {
       
  2094     MPX_FUNC("CMPXDbHandler::RemoveSongsMatchingArtistAndAlbumL");
       
  2095 
       
  2096     // get the songs for the specified artist and album
       
  2097     CMPXMediaArray* songs = CMPXMediaArray::NewL();
       
  2098     CleanupStack::PushL(songs);
       
  2099 
       
  2100     RArray<TMPXAttribute> attributes;
       
  2101     CleanupClosePushL (attributes);
       
  2102     attributes.AppendL(KMPXMediaGeneralId);
       
  2103 
       
  2104     iDbMusic->GetSongsForArtistAndAlbumL(aArtistId, aAlbumId, attributes.Array(), *songs);
       
  2105     CleanupStack::PopAndDestroy(&attributes);
       
  2106 
       
  2107     // iterate the songs and remove them one by one
       
  2108     // so records in the category tables can also be updated
       
  2109     TInt count(songs->Count());
       
  2110     for (TInt index = 0; index < count; ++index)
       
  2111         {
       
  2112         CMPXMedia* song = (*songs)[index];
       
  2113         if (song->IsSupported(KMPXMediaGeneralId))
       
  2114             {
       
  2115             DoRemoveSongL( song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),
       
  2116                 aUriArray, aItemChangedMessages, EFalse);
       
  2117             DoRemoveSongFromPlaylistL(song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId),aItemChangedMessages);
       
  2118             }
       
  2119         }
       
  2120 
       
  2121     CleanupStack::PopAndDestroy(songs);
       
  2122     }
       
  2123 
       
  2124 // ----------------------------------------------------------------------------
       
  2125 // Remove all playlists from collection
       
  2126 // ----------------------------------------------------------------------------
       
  2127 //
       
  2128 void CMPXDbHandler::DoRemoveAllPlaylistsL()
       
  2129     {
       
  2130     MPX_FUNC("CMPXDbHandler::DoRemoveAllPlaylistsL");
       
  2131     iDbPlaylist->DeleteAllPlaylistsL();
       
  2132     }
       
  2133 
       
  2134 // ----------------------------------------------------------------------------
       
  2135 // Remove specified playlist
       
  2136 // ----------------------------------------------------------------------------
       
  2137 //
       
  2138 void CMPXDbHandler::DoRemovePlaylistL(
       
  2139     TUint32 aPlaylistId,
       
  2140     CDesCArray& aUriArray,
       
  2141     CMPXMessageArray& aItemChangedMessages)
       
  2142     {
       
  2143     MPX_FUNC("CMPXDbHandler::DoRemovePlaylistL");
       
  2144 
       
  2145     HBufC* uri(iDbPlaylist->DeletePlaylistL(aPlaylistId));
       
  2146     if (uri)
       
  2147         {
       
  2148         CleanupStack::PushL(uri);
       
  2149         aUriArray.AppendL(*uri);
       
  2150         CleanupStack::PopAndDestroy(uri);
       
  2151         }
       
  2152 
       
  2153     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aPlaylistId, EMPXItemDeleted,
       
  2154         EMPXPlaylist, KDBPluginUid);
       
  2155     }
       
  2156 
       
  2157 // ----------------------------------------------------------------------------
       
  2158 // Remove song from playlist songs table
       
  2159 // ----------------------------------------------------------------------------
       
  2160 //
       
  2161 void CMPXDbHandler::DoRemoveSongFromPlaylistL(
       
  2162     TUint32 aPlaylistId,
       
  2163     const TMPXItemId& aSongId,
       
  2164     TInt aOrdinal,
       
  2165     CMPXMessageArray& aItemChangedMessages)
       
  2166     {
       
  2167     MPX_FUNC("CMPXDbHandler::DoRemoveSongFromPlaylistL");
       
  2168     MPX_DEBUG5("CMPXDbHandler::DoRemoveSongFromPlaylistL(playlist 0x%x, songId [0x%x,0x%x], ordinal %d)",
       
  2169         aPlaylistId, aSongId.iId1, aSongId.iId2, aOrdinal);
       
  2170 
       
  2171     // delete the song
       
  2172     iDbPlaylist->DeleteSongL(aPlaylistId, aSongId.iId2, aOrdinal);
       
  2173 
       
  2174     // Send a playlist modified message
       
  2175     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aPlaylistId, EMPXItemModified,
       
  2176         EMPXPlaylist, KDBPluginUid);
       
  2177 
       
  2178     // Send a message on the song in the playlist that is deleted
       
  2179     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, aSongId, EMPXItemDeleted,
       
  2180         EMPXSong, KDBPluginUid);
       
  2181     }
       
  2182 
       
  2183 // ----------------------------------------------------------------------------
       
  2184 // CMPXDbHandler::DoCleanupDeletedRecordsL
       
  2185 // ----------------------------------------------------------------------------
       
  2186 //
       
  2187 void CMPXDbHandler::DoCleanupDeletedRecordsL()
       
  2188     {
       
  2189     MPX_FUNC("CMPXDbHandler::DoCleanupDeletedRecordsL");
       
  2190 
       
  2191     // delete all marked records from the Music table
       
  2192     iDbMusic->CleanupL();
       
  2193 
       
  2194     // reset the count in the Auxiliary table
       
  2195     iDbAuxiliary->SetSaveDeletedRecordCountL(KDbManagerAllDrives,0);
       
  2196     }
       
  2197 
       
  2198 // ----------------------------------------------------------------------------
       
  2199 // FindAllL
       
  2200 // ----------------------------------------------------------------------------
       
  2201 //
       
  2202 void CMPXDbHandler::FindAllL(
       
  2203     const CMPXMedia& aCriteria,
       
  2204     const TArray<TMPXAttribute>& aAttrs,
       
  2205     CMPXMediaArray* aMediaArray)
       
  2206     {
       
  2207     MPX_FUNC("CMPXDbHandler::FindAllL");
       
  2208 
       
  2209     RArray<TMPXAttribute> attributes;
       
  2210     CleanupClosePushL(attributes);
       
  2211     MPXUser::MergeAttributeL(aAttrs, attributes);
       
  2212 
       
  2213     TMPXGeneralCategory category = aCriteria.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  2214     switch (category)
       
  2215         {
       
  2216         case EMPXPlaylist:
       
  2217             {
       
  2218             TUint32 playlistId(0);
       
  2219             if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2220                 {
       
  2221                 playlistId = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  2222                 }
       
  2223 
       
  2224             if (iAutoPlaylist->AutoPlaylistTypeL(playlistId) != EMPXNoAutoPlaylist)
       
  2225                 {
       
  2226                 CMPXMedia* media = CMPXMedia::NewL();
       
  2227                 CleanupStack::PushL(media);
       
  2228 
       
  2229                 iAutoPlaylist->GetPlaylistL(playlistId, aAttrs, *media);
       
  2230 
       
  2231                 aMediaArray->AppendL(*media);
       
  2232                 CleanupStack::PopAndDestroy(media);
       
  2233                 }
       
  2234             else
       
  2235                 {
       
  2236                 iDbPlaylist->FindAllL(aCriteria, attributes.Array(), *aMediaArray);
       
  2237                 }
       
  2238 
       
  2239             break;
       
  2240             }
       
  2241         case EMPXSong:
       
  2242             {
       
  2243             FindSongL(aCriteria, attributes.Array(), *aMediaArray);
       
  2244             break;
       
  2245             }
       
  2246         default:
       
  2247             {
       
  2248             DbCategoryL(category)->FindAllL(aCriteria, attributes.Array(), *aMediaArray);
       
  2249             break;
       
  2250             }
       
  2251         }
       
  2252 
       
  2253     CleanupStack::PopAndDestroy(&attributes);
       
  2254     }
       
  2255 
       
  2256 // ----------------------------------------------------------------------------
       
  2257 // Get song(s) from the music table that match the given criteria
       
  2258 // ----------------------------------------------------------------------------
       
  2259 //
       
  2260 void CMPXDbHandler::FindSongL(
       
  2261     const CMPXMedia& aCriteria,
       
  2262     const TArray<TMPXAttribute>& aAttrs,
       
  2263     CMPXMediaArray& aMediaArray)
       
  2264     {
       
  2265     MPX_FUNC("CMPXDbCollection::FindSongL");
       
  2266 
       
  2267     TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
  2268 
       
  2269     TUint32 id(0);
       
  2270     if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2271         {
       
  2272         id = (aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId)).iId2;
       
  2273         }
       
  2274 
       
  2275     TUint32 containerId(0);
       
  2276     if (aCriteria.IsSupported(KMPXMediaGeneralContainerId))
       
  2277         {
       
  2278         containerId = aCriteria.ValueTObjectL<TUint32>(KMPXMediaGeneralContainerId);
       
  2279         }
       
  2280 
       
  2281     //////////////////////////////////////////////////////////////////////
       
  2282     // Find songs in the specified playlist
       
  2283     //////////////////////////////////////////////////////////////////////
       
  2284     TMPXGeneralCategory cat(MPX_ITEM_CATEGORY(id));
       
  2285 
       
  2286     if (type == EMPXGroup &&
       
  2287         (cat == EMPXPlaylist ||
       
  2288         MPX_ITEM_CATEGORY(containerId) == EMPXPlaylist))
       
  2289         {
       
  2290         TUint32 playlistId = (cat == EMPXPlaylist) ?
       
  2291             id : (containerId & KMCCategoryMask);
       
  2292 
       
  2293         GetPlaylistSongsL(playlistId, aAttrs, aMediaArray);
       
  2294         }
       
  2295 
       
  2296     //////////////////////////////////////////////////////////////////////
       
  2297     // Find a particular song in the specified playlist. This fills the
       
  2298     // song with info from Playlist table first then overwrites it with
       
  2299     // info from Songs table if Songs table where this song is located
       
  2300     // is present in order to support the display of song titles in a
       
  2301     // playlist when memory card is removed if the playlist refers to
       
  2302     // songs on the memory card. Caller of this scenario is OpenL/MediaL.
       
  2303     // When user attempts to play a track in an auto-playlist, we will
       
  2304     // find the song from Songs table directly since auto-playlists are
       
  2305     // not stored in the Playlist table. Auto-playlists are query-based,
       
  2306     // therefore, when memory card is removed, songs on the memory card
       
  2307     // will not be shown in the auto-playlist; hence they do not exhibit
       
  2308     // the same challenge as user created playlists.
       
  2309     //////////////////////////////////////////////////////////////////////
       
  2310     else if (type == EMPXItem &&
       
  2311         cat == EMPXCollection &&
       
  2312         MPX_ITEM_CATEGORY(containerId) == EMPXPlaylist)
       
  2313         {
       
  2314         if (iAutoPlaylist->AutoPlaylistTypeL(containerId) != EMPXNoAutoPlaylist)
       
  2315             {
       
  2316             // auto playlist song, get the song details from the music table
       
  2317             iDbMusic->FindSongsL(id, 0, type, aCriteria, aAttrs, aMediaArray);
       
  2318             }
       
  2319         else
       
  2320             {
       
  2321             GetPlaylistSongL(id, containerId, aAttrs, aMediaArray);
       
  2322             }
       
  2323         }
       
  2324 
       
  2325     //////////////////////////////////////////////////////////////////////
       
  2326     // Find all songs, all songs in a particular album and/or artist, or
       
  2327     // a particular song
       
  2328     //////////////////////////////////////////////////////////////////////
       
  2329     else
       
  2330         {
       
  2331         iDbMusic->FindSongsL(id, containerId, type, aCriteria, aAttrs, aMediaArray);
       
  2332         }
       
  2333     }
       
  2334 
       
  2335 // ----------------------------------------------------------------------------
       
  2336 // Get song(s) in the specified playlist
       
  2337 // ----------------------------------------------------------------------------
       
  2338 //
       
  2339 void CMPXDbHandler::GetPlaylistSongsL(
       
  2340     TUint32 aPlaylistId,
       
  2341     const TArray<TMPXAttribute>& aAttrs,
       
  2342     CMPXMediaArray& aMediaArray)
       
  2343     {
       
  2344     MPX_FUNC("CMPXDbHandler::GetPlaylistSongsL");
       
  2345     MPX_DEBUG2("CMPXDbHandler::GetPlaylistSongsL(0x%x)", aPlaylistId);
       
  2346 
       
  2347     // check the auto playlists first
       
  2348     if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist))
       
  2349         {
       
  2350         iDbMusic->GetRecentlyPlayedSongsL(aAttrs, aMediaArray);
       
  2351         }
       
  2352     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist))
       
  2353         {
       
  2354         iDbMusic->GetMostPlayedSongsL(aAttrs, aMediaArray);
       
  2355         }
       
  2356     else if (aPlaylistId == iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyAddedPlaylist))
       
  2357         {
       
  2358         iDbMusic->GetRecentlyAddedSongsL(aAttrs, aMediaArray);
       
  2359         }
       
  2360     else
       
  2361         {
       
  2362         TInt attrCount(aAttrs.Count());
       
  2363         if ( attrCount > 1 || (attrCount == 1 && !(aAttrs[0] == KMPXMediaGeneralId)) )
       
  2364             {
       
  2365 	        TInt plDrive(iDbPlaylist->GetDriveIdL(aPlaylistId));
       
  2366 	        MPX_TRAPD(err, iDbMusic->GetAllSongsL(plDrive, aPlaylistId, aAttrs, aMediaArray));
       
  2367 
       
  2368 	        // song not found in Music table
       
  2369 	        if (err == KErrNotFound)
       
  2370 	            {
       
  2371 	            //
       
  2372 	            // Leave with KErrNotFound if one of the following is true:
       
  2373 	            // 1) the requested song is in an auto playlist. Since auto-playlist isn't
       
  2374 	            //    stored in playlist tables, we won't be able to retrieve info elsewhere
       
  2375 	            // 2) the requested song is in a user playlist but we cannot find the song
       
  2376 	            //    info from playlist tables either
       
  2377 	            //
       
  2378 	           if (EMPXNoAutoPlaylist != iAutoPlaylist->AutoPlaylistTypeL(aPlaylistId) ||
       
  2379 	                !iDbPlaylist->Songs().GetSongsL(aPlaylistId, aAttrs, aMediaArray))
       
  2380 	               {
       
  2381 	               User::Leave(KErrNotFound);
       
  2382 	               }
       
  2383 	            }
       
  2384 	        else
       
  2385 	            {
       
  2386 	            // ignore the error if KErrNotFound
       
  2387 	            User::LeaveIfError(err);
       
  2388 	            }
       
  2389             }
       
  2390         else
       
  2391             {
       
  2392             // get ids of the songs in the playlist
       
  2393             iDbPlaylist->Songs().GetSongsL(aPlaylistId, aMediaArray);
       
  2394             }
       
  2395         }
       
  2396     }
       
  2397 
       
  2398 // ----------------------------------------------------------------------------
       
  2399 // Find all albums or the albums for a specified artist
       
  2400 // ----------------------------------------------------------------------------
       
  2401 //
       
  2402 void CMPXDbHandler::FindAlbumL(
       
  2403     const CMPXMedia& aCriteria,
       
  2404     const TArray<TMPXAttribute>& aAttrs,
       
  2405     CMPXMediaArray& aMediaArray)
       
  2406     {
       
  2407     MPX_FUNC("CMPXDbHandler::FindAlbumL");
       
  2408 
       
  2409     TMPXGeneralType type = aCriteria.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType);
       
  2410 
       
  2411     TUint32 id(0);
       
  2412     if (aCriteria.IsSupported(KMPXMediaGeneralId))
       
  2413         {
       
  2414         id = aCriteria.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2415         }
       
  2416 
       
  2417     if ((type == EMPXGroup) && (MPX_ITEM_CATEGORY(id) == EMPXArtist))
       
  2418         {
       
  2419         // get all the albums for the artist
       
  2420         GetAlbumsMatchingArtistL(id, aAttrs, aMediaArray);
       
  2421         }
       
  2422     else
       
  2423         {
       
  2424         // look up all albums from album table
       
  2425         iDbAlbum->FindAllL(aCriteria, aAttrs, aMediaArray);
       
  2426         }
       
  2427     }
       
  2428 
       
  2429 // ----------------------------------------------------------------------------
       
  2430 // Extracts the playlist ID and drive ID from a playlist media instance
       
  2431 // ----------------------------------------------------------------------------
       
  2432 //
       
  2433 void CMPXDbHandler::ProcessPlaylistMediaL(
       
  2434     CMPXMedia& aMedia,
       
  2435     TUint32& aPlaylistId,
       
  2436     TInt& aPlaylistDriveId)
       
  2437     {
       
  2438     MPX_FUNC("CMPXDbHandler::ProcessPlaylistMediaL");
       
  2439 
       
  2440     if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  2441         {
       
  2442         aPlaylistId = aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2443 
       
  2444         if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  2445             {
       
  2446             // find drive id of the playlist
       
  2447             aPlaylistDriveId = TDriveUnit(aMedia.ValueText(KMPXMediaGeneralUri));
       
  2448             }
       
  2449         else
       
  2450             {
       
  2451             // Find drive Id(s) of corresponding Playlist Id
       
  2452             aPlaylistDriveId = iDbPlaylist->GetDriveIdL(aPlaylistId);
       
  2453             }
       
  2454         }
       
  2455     else if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  2456         {
       
  2457         const TDesC& playlistUri = aMedia.ValueText(KMPXMediaGeneralUri);
       
  2458         // find drive id of the playlist
       
  2459         aPlaylistDriveId = TDriveUnit(playlistUri);
       
  2460 
       
  2461         // aMedia does not have an ID, make sure the add it
       
  2462         aPlaylistId = GetPlaylistIdMatchingUriL(playlistUri);
       
  2463         aMedia.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPlaylistId);
       
  2464         }
       
  2465     else
       
  2466         {
       
  2467         User::Leave(KErrArgument);
       
  2468         }
       
  2469     }
       
  2470 
       
  2471 // ----------------------------------------------------------------------------
       
  2472 // Makes sure that all songs in the specified playlist have the ID, title and URI attributes
       
  2473 // ----------------------------------------------------------------------------
       
  2474 //
       
  2475 void CMPXDbHandler::UpdatePlaylistSongInfoL(
       
  2476     CMPXMedia& aMedia)
       
  2477     {
       
  2478     MPX_FUNC("CMPXDbHandler::UpdatePlaylistSongInfoL");
       
  2479 
       
  2480     CMPXMediaArray* mediaArray = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  2481     User::LeaveIfNull(mediaArray);
       
  2482 
       
  2483     // make sure each song has Id, Uri, and Title before they can be added to playlist
       
  2484     TInt count(mediaArray->Count());
       
  2485     for (TInt i = 0; i < count; ++i)
       
  2486         {
       
  2487         CMPXMedia* element = mediaArray->AtL(i);
       
  2488 
       
  2489         // copy each song to deal w/ global heap issues
       
  2490         CMPXMedia* entry = CMPXMedia::NewL(*element);
       
  2491         CleanupStack::PushL(entry);
       
  2492 
       
  2493         // song has everything, go to next song
       
  2494         if (entry->IsSupported(KMPXMediaGeneralUri) &&
       
  2495             entry->IsSupported(KMPXMediaGeneralId) &&
       
  2496             entry->IsSupported(KMPXMediaGeneralTitle))
       
  2497             {
       
  2498             // pop entry to maintain CleanupStack
       
  2499             CleanupStack::PopAndDestroy(entry);
       
  2500             continue;
       
  2501             }
       
  2502 
       
  2503         // songs must contain (at minimum) an Uri or an Id
       
  2504         if (!entry->IsSupported(KMPXMediaGeneralUri) &&
       
  2505             !entry->IsSupported(KMPXMediaGeneralId))
       
  2506             {
       
  2507             User::Leave(KErrArgument);
       
  2508             }
       
  2509 
       
  2510         // get Id
       
  2511         if (!entry->IsSupported(KMPXMediaGeneralId))
       
  2512             {
       
  2513             // fill in the ID if not present
       
  2514             TParsePtrC parser(entry->ValueText(KMPXMediaGeneralUri));
       
  2515             entry->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId,
       
  2516                 MPXDbCommonUtil::GenerateUniqueIdL(iFs, EMPXCollection, parser.FullName(), EFalse));
       
  2517             }
       
  2518 
       
  2519         CMPXMedia* song(NULL);
       
  2520 
       
  2521         // update songs info
       
  2522         TInt error(iDbMusic->GetSongL(*entry, song));
       
  2523         TBool result (ETrue);
       
  2524 
       
  2525         // error can only be KErrNone or KErrNotFound
       
  2526         // from CMPXDbMusic::GetSongL
       
  2527         // if not found in Music, get info from PlaylistSongs (PlaylistSongs & PlaylistSongInfo) DB
       
  2528         if (error == KErrNotFound)
       
  2529             {
       
  2530             RArray<TMPXAttribute> attributes;
       
  2531             CleanupClosePushL(attributes);
       
  2532             attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral,
       
  2533                 EMPXMediaGeneralId | EMPXMediaGeneralTitle | EMPXMediaGeneralUri | EMPXMediaGeneralFlags));
       
  2534 
       
  2535             // this song doesn't exist in Music table. This song is either a broken link or
       
  2536             // is of an unsupported song type that exists in the file system. Broken links
       
  2537             // have already been marked as such during playlist import.
       
  2538             result = iDbPlaylist->Songs().GetSongL(entry->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId), attributes.Array(), song);
       
  2539             if (!result)
       
  2540                 {
       
  2541                 // song is a broken link
       
  2542                 //TUint flags = KMPXMediaGeneralFlagsSetOrUnsetBit;
       
  2543                 //flags |= KMPXMediaGeneralFlagsIsInvalid; // set flag
       
  2544                 //t->SetTObjectValueL<TUint>( KMPXMediaGeneralFlags, flags );
       
  2545 
       
  2546                 if (entry->IsSupported(KMPXMediaGeneralUri))
       
  2547                     {
       
  2548                     // no valid Id but has Uri, just verify Title is present
       
  2549                     // this is the case if the song is a broken link or podcast
       
  2550                     if (!entry->IsSupported(KMPXMediaGeneralTitle))
       
  2551                         {
       
  2552                         // does not have Title, make up the Title from file name
       
  2553                         TParsePtrC parser(entry->ValueText(KMPXMediaGeneralUri));
       
  2554                         entry->SetTextValueL(KMPXMediaGeneralTitle, parser.Name());
       
  2555                         }
       
  2556                     }
       
  2557                 else
       
  2558                     {
       
  2559                     // no valid Id & no Uri, bad argument
       
  2560                     User::Leave(KErrArgument);
       
  2561                     }
       
  2562                 }
       
  2563             CleanupStack::PopAndDestroy(&attributes);
       
  2564             }
       
  2565 
       
  2566         // update attributes
       
  2567         CleanupStack::PushL(song);
       
  2568 
       
  2569         // song not found in Music or Playlist DB, update entry
       
  2570         if(error == KErrNotFound && !result)
       
  2571             {
       
  2572             mediaArray->InsertL(*entry,i);
       
  2573             }
       
  2574         else  // found in DB, replace entry
       
  2575             {
       
  2576             mediaArray->InsertL(*song,i);
       
  2577             }
       
  2578 
       
  2579         // replace element in the array
       
  2580         CleanupStack::PopAndDestroy(song);
       
  2581         CleanupStack::PopAndDestroy(entry);
       
  2582         mediaArray->Remove(i+1);
       
  2583         }
       
  2584     }
       
  2585 
       
  2586 // ----------------------------------------------------------------------------
       
  2587 // CMPXDbHandler::ProcessMusicFoldersL
       
  2588 // ----------------------------------------------------------------------------
       
  2589 //
       
  2590 void CMPXDbHandler::ProcessMusicFoldersL(
       
  2591     const CDesCArray& aFolders)
       
  2592     {
       
  2593     MPX_FUNC("CMPXDbHandler::ProcessMusicFoldersL");
       
  2594 
       
  2595     TInt count(aFolders.MdcaCount());
       
  2596     for (TInt i = 0; i < count; ++i)
       
  2597         {
       
  2598         TPtrC16 folder = aFolders.MdcaPoint(i);
       
  2599 
       
  2600         // check if disk is inserted and act accordingly
       
  2601         TDriveUnit driveUnit(folder);
       
  2602         if (!iFs.IsValidDrive(driveUnit))
       
  2603             {
       
  2604             User::Leave(KErrArgument);
       
  2605             }
       
  2606 
       
  2607         // append the drive to the drive list
       
  2608         iDbDrives.AppendL(driveUnit);
       
  2609 
       
  2610         // make sure the folder is created
       
  2611         TVolumeInfo info;
       
  2612         if (iFs.Volume(info, driveUnit) == KErrNone)
       
  2613            {
       
  2614             if (!BaflUtils::PathExists(iFs, folder))
       
  2615                 {
       
  2616                 // create music folder if necessary
       
  2617                 TInt err(iFs.MkDirAll(folder));
       
  2618                 MPX_DEBUG3("Try to create music folder %S return code %d", &folder, err);
       
  2619                 if (err != KErrAlreadyExists)
       
  2620                     {
       
  2621                     User::LeaveIfError(err);
       
  2622                     }
       
  2623                 }
       
  2624             }
       
  2625         }
       
  2626     }
       
  2627 
       
  2628 // ----------------------------------------------------------------------------
       
  2629 // CMPXDbHandler::DbCategoryL
       
  2630 // ----------------------------------------------------------------------------
       
  2631 //
       
  2632 CMPXDbCategory* CMPXDbHandler::DbCategoryL(
       
  2633     TMPXGeneralCategory aCategory) const
       
  2634     {
       
  2635     MPX_FUNC("CMPXDbHandler::DbCategoryL");
       
  2636 
       
  2637     CMPXDbCategory* dbCategory(NULL);
       
  2638     switch (aCategory)
       
  2639         {
       
  2640         case EMPXArtist:
       
  2641             {
       
  2642             dbCategory = (CMPXDbCategory*)iDbArtist;
       
  2643             break;
       
  2644             }
       
  2645         case EMPXAlbum:
       
  2646             {
       
  2647             dbCategory = (CMPXDbCategory*)iDbAlbum;
       
  2648             break;
       
  2649             }
       
  2650         case EMPXGenre:
       
  2651             {
       
  2652             dbCategory = (CMPXDbCategory*)iDbGenre;
       
  2653             break;
       
  2654             }
       
  2655         case EMPXComposer:
       
  2656             {
       
  2657             dbCategory = (CMPXDbCategory*)iDbComposer;
       
  2658             break;
       
  2659             }
       
  2660         default:
       
  2661             User::Leave(KErrNotSupported);
       
  2662         }
       
  2663 
       
  2664     return dbCategory;
       
  2665     }
       
  2666 
       
  2667 // ----------------------------------------------------------------------------
       
  2668 // Verifies that the volume ID of the database matches the drive
       
  2669 // ----------------------------------------------------------------------------
       
  2670 //
       
  2671 void CMPXDbHandler::VerifyVolumeIdL()
       
  2672     {
       
  2673     MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL <--");
       
  2674 
       
  2675     TInt count( iDbDrives.Count() );
       
  2676     for( TInt i=0; i<count; ++i )
       
  2677         {
       
  2678         if( iDbManager->IsOpen( iDbDrives[i] ) )
       
  2679             {
       
  2680             TVolumeInfo volInfo;
       
  2681             iFs.Volume(volInfo, iDbDrives[i] );
       
  2682             TUint curId(volInfo.iUniqueID);
       
  2683 
       
  2684             TInt volId = iDbAuxiliary->IdL( iDbDrives[i] );
       
  2685 
       
  2686             // New database, no volume id set, mask out top bit because this is an uint
       
  2687             //
       
  2688             MPX_DEBUG3("CMPXDBHandler::VerifyVolumeIdL drive:%i db:%i", curId, volId);
       
  2689             if( volId == 0 )
       
  2690                 {
       
  2691                 MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -- New ID");
       
  2692                 BeginTransactionL();
       
  2693                 TRAPD( err, iDbAuxiliary->SetIdL( iDbDrives[i], curId&0x7FFFFFFF ) );
       
  2694                 EndTransactionL( err );
       
  2695                 
       
  2696                 // KSqlDbCorrupted indicates DB corrupted, need to recreate.
       
  2697                 if ( err == KSqlDbCorrupted )
       
  2698                     {
       
  2699                     MPX_DEBUG1("CMPXPodcastDbHandler::VerifyVolumeIdL -- Corrupted DB");     
       
  2700                     iDbManager->RecreateDatabaseL(iDbDrives[i]);
       
  2701                     BeginTransactionL();
       
  2702                     TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
       
  2703                     EndTransactionL( err );
       
  2704                     }
       
  2705                 }
       
  2706             // Unmatched volume id, mark db as corrupt and break
       
  2707             //
       
  2708             else if ( (curId&0x7FFFFFFF) != (volId&0x7FFFFFFFF) )
       
  2709                 {
       
  2710                 MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -- ID match FAILED");
       
  2711                 iDbManager->RecreateDatabaseL(iDbDrives[i]);
       
  2712                 BeginTransactionL();
       
  2713                 TRAPD(err, iDbAuxiliary->SetDBCorruptedL( ETrue ) );
       
  2714                 EndTransactionL( err );
       
  2715                 }
       
  2716             }
       
  2717         }
       
  2718     MPX_DEBUG1("CMPXDbHandler::VerifyVolumeIdL -->");
       
  2719     }
       
  2720 
       
  2721 
       
  2722 // ----------------------------------------------------------------------------
       
  2723 // Checks if there is a drive that has a low disk space
       
  2724 // ----------------------------------------------------------------------------
       
  2725 //
       
  2726 void CMPXDbHandler::CheckDiskSpaceOnDrivesL()
       
  2727     {
       
  2728     MPX_DEBUG1("CMPXDbHandler::CheckDiskSpaceOnDrivesL <--");
       
  2729 
       
  2730     TInt count( iDbDrives.Count() );
       
  2731     for( TInt index=0; index<count; ++index )
       
  2732         {
       
  2733         iDbManager->CheckDiskSpaceL(iDbDrives[index]);
       
  2734         }
       
  2735     MPX_DEBUG1("CMPXDbHandler::CheckDiskSpaceOnDrivesL -->");
       
  2736     }
       
  2737 
       
  2738 #if defined (__MTP_PROTOCOL_SUPPORT)
       
  2739 
       
  2740 // ----------------------------------------------------------------------------
       
  2741 // CMPXDbHandler::SaveDeletedSongs
       
  2742 // ----------------------------------------------------------------------------
       
  2743 //
       
  2744 TBool CMPXDbHandler::SaveDeletedSongs()
       
  2745     {
       
  2746     MPX_FUNC("CMPXDbHandler::SaveDeletedSongs");
       
  2747 
       
  2748     TBool saveDeletedSongs(ETrue);
       
  2749     CRepository* cenrep(NULL);
       
  2750     MPX_TRAPD(error, cenrep = CRepository::NewL(KMPXMtpSettings));
       
  2751     if (!error)
       
  2752         {
       
  2753         cenrep->Get(KMPXMtpSaveDeletedRecordFlag, saveDeletedSongs);
       
  2754         delete cenrep;
       
  2755         MPX_DEBUG2("MTP indicated to save deleted songs? %d", saveDeletedSongs);
       
  2756         }
       
  2757 
       
  2758     return saveDeletedSongs;
       
  2759     }
       
  2760 
       
  2761 #endif
       
  2762 
       
  2763 #ifdef RD_MULTIPLE_DRIVE
       
  2764 
       
  2765 // ----------------------------------------------------------------------------------------------------------
       
  2766 // Retrieve all visible music folder locations
       
  2767 // ----------------------------------------------------------------------------------------------------------
       
  2768 //
       
  2769 CDesCArrayFlat* CMPXDbHandler::GetMusicFoldersL()
       
  2770     {
       
  2771     MPX_FUNC("CMPXDbHandler::GetMusicFoldersL()");
       
  2772     TDriveList driveList;
       
  2773     TInt driveCount(0);
       
  2774     User::LeaveIfError(DriveInfo::GetUserVisibleDrives(iFs, driveList, driveCount));
       
  2775     MPX_DEBUG2 ("CMPXDbHandler::GetMusicFoldersL() - driveCount = %d", driveCount);
       
  2776 
       
  2777     CDesCArrayFlat* folders = new (ELeave) CDesCArrayFlat(1); // granularity
       
  2778     CleanupStack::PushL(folders);
       
  2779 
       
  2780     for (TInt i = EDriveA; i <= EDriveZ; i++)
       
  2781         {
       
  2782         if ((driveList[i]) && (!IsRemoteDrive(static_cast<TDriveNumber>(i))))
       
  2783             {
       
  2784             if (i == EDriveC)
       
  2785                 {
       
  2786                 // Append the default phone memory path to the list
       
  2787                 // of music folders
       
  2788                 TPtrC rootPath(PathInfo::PhoneMemoryRootPath());
       
  2789                 folders->AppendL(rootPath);
       
  2790                 MPX_DEBUG2("CMPXDbHandler::GetMusicFoldersL() - adding...%S", &rootPath);
       
  2791                 }
       
  2792             else
       
  2793                 {
       
  2794                 // Get drive letter
       
  2795                 TChar driveChar;
       
  2796                 User::LeaveIfError(iFs.DriveToChar(i, driveChar));
       
  2797 
       
  2798                 // Append visible drive to list of music folders
       
  2799                 TBuf<2> drive;
       
  2800                 drive.Append(driveChar);
       
  2801                 drive.Append(_L(":"));
       
  2802                 folders->AppendL(drive);
       
  2803                 MPX_DEBUG2 ("CMPXDbHandler::GetMusicFoldersL() - adding...%S", &drive);
       
  2804                 }
       
  2805             }
       
  2806         }
       
  2807 
       
  2808     CleanupStack::Pop(folders);
       
  2809     return folders;
       
  2810     }
       
  2811 
       
  2812 #endif // RD_MULTIPLE_DRIVE
       
  2813 
       
  2814 // ----------------------------------------------------------------------------
       
  2815 // CMPXDbHandler::AddCategoryItemL
       
  2816 // ----------------------------------------------------------------------------
       
  2817 //
       
  2818 TUint32 CMPXDbHandler::AddCategoryItemL(
       
  2819     TMPXGeneralCategory aCategory,
       
  2820     const TDesC& aName,
       
  2821     TInt aDriveId,
       
  2822     CMPXMessageArray* aItemChangedMessages,
       
  2823     TBool& aItemExist)
       
  2824     {
       
  2825     MPX_FUNC("CMPXDbHandler::AddCategoryItemL()");
       
  2826 
       
  2827     MPX_PERF_START(CMPXDbHandler_AddCategoryItemL);
       
  2828 
       
  2829     TBool newRecord(EFalse);
       
  2830     TUint32 id(DbCategoryL(aCategory)->AddItemL(aName, aDriveId, newRecord, (aCategory != EMPXGenre)));
       
  2831     if (newRecord && aItemChangedMessages)
       
  2832         {
       
  2833         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemInserted,
       
  2834             aCategory, KDBPluginUid);
       
  2835         }
       
  2836     // when the added item's category is Genre or Composer,
       
  2837     // and it is NOT a new record,
       
  2838     // we should send the item number changed message
       
  2839     else if ( ( aCategory == EMPXGenre || aCategory == EMPXComposer ) &&
       
  2840     		!newRecord && aItemChangedMessages )
       
  2841         {
       
  2842         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemModified,
       
  2843             aCategory, KDBPluginUid);
       
  2844         }
       
  2845     aItemExist = !newRecord;
       
  2846     MPX_PERF_END(CMPXDbHandler_AddCategoryItemL);
       
  2847 
       
  2848     return id;
       
  2849     }
       
  2850 
       
  2851 TUint32 CMPXDbHandler::AddCategoryItemL(
       
  2852         TMPXGeneralCategory aCategory,
       
  2853         const TDesC& aName,
       
  2854         TUint32 aArtist,
       
  2855         const TDesC& aArt,
       
  2856         TInt aDriveId,
       
  2857         CMPXMessageArray* aItemChangedMessages,
       
  2858         TBool& aItemExist)
       
  2859 	{
       
  2860     MPX_FUNC("CMPXDbHandler::AddCategoryItemL()");
       
  2861 
       
  2862     MPX_PERF_START(CMPXDbHandler_AddCategoryItemL);
       
  2863 
       
  2864     TBool newRecord(EFalse);
       
  2865 
       
  2866     TUint32 id = 0;
       
  2867     if ( aArtist )
       
  2868         {
       
  2869         id = iDbAlbum->AddItemL(aName, aArtist, aArt, aDriveId, newRecord, (aCategory != EMPXGenre));
       
  2870         }
       
  2871     else
       
  2872         {
       
  2873         id = iDbArtist->AddItemL(aName, aArt, aDriveId, newRecord, (aCategory != EMPXGenre));
       
  2874         }
       
  2875         
       
  2876     if (newRecord && aItemChangedMessages)
       
  2877         {
       
  2878         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemInserted,
       
  2879             aCategory, KDBPluginUid);
       
  2880         }
       
  2881     // when the added item's category is Artist, and it is NOT a new record,
       
  2882     // we should send the item number changed message
       
  2883     else if (  aCategory == EMPXArtist &&
       
  2884     		!newRecord && aItemChangedMessages )
       
  2885         {
       
  2886         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, id, EMPXItemModified,
       
  2887             aCategory, KDBPluginUid);
       
  2888         }
       
  2889     aItemExist = !newRecord;
       
  2890     MPX_PERF_END(CMPXDbHandler_AddCategoryItemL);
       
  2891 
       
  2892     return id;
       
  2893 	}
       
  2894 
       
  2895 void CMPXDbHandler::UpdateCategoryItemL(
       
  2896 		TMPXGeneralCategory aCategory,
       
  2897 		TUint32 aCategoryId,
       
  2898 		const CMPXMedia& aMedia,
       
  2899 		TInt aDrive, 
       
  2900 		CMPXMessageArray* aItemChangedMessages)
       
  2901 	{
       
  2902 	switch(aCategory)
       
  2903 	    {
       
  2904 	    case EMPXAlbum:
       
  2905             iDbAlbum->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
       
  2906 	        break;
       
  2907 	        
       
  2908 	    case EMPXArtist:
       
  2909 	        iDbArtist->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
       
  2910 	        break;
       
  2911 
       
  2912 	    default:
       
  2913             DbCategoryL(aCategory)->UpdateItemL(aCategoryId, aMedia, aDrive, aItemChangedMessages);
       
  2914 	        break;
       
  2915 	    }
       
  2916 	}
       
  2917 // ----------------------------------------------------------------------------
       
  2918 // CMPXDbHandler::DeleteSongForCategoryL
       
  2919 // ----------------------------------------------------------------------------
       
  2920 //
       
  2921 void CMPXDbHandler::DeleteSongForCategoryL(
       
  2922     TMPXGeneralCategory aCategory,
       
  2923     TUint32 aCategoryId,
       
  2924     TInt aDriveId,
       
  2925     CMPXMessageArray* aItemChangedMessages,
       
  2926     TBool& aItemExist)
       
  2927     {
       
  2928     MPX_FUNC("CMPXDbHandler::DeleteSongForCategoryL");
       
  2929     DbCategoryL(aCategory)->DecrementSongsForCategoryL(aCategoryId, aDriveId,
       
  2930         aItemChangedMessages, aItemExist);
       
  2931     }
       
  2932 
       
  2933 // ----------------------------------------------------------------------------
       
  2934 // CMPXDbHandler::HandlePlayCountModifiedL
       
  2935 // ----------------------------------------------------------------------------
       
  2936 //
       
  2937 void CMPXDbHandler::HandlePlayCountModifiedL(
       
  2938     CMPXMessageArray& aItemChangedMessages)
       
  2939     {
       
  2940     MPX_FUNC("CMPXDbHandler::HandlePlayCountModifiedL");
       
  2941 
       
  2942     TUint32 plId(iAutoPlaylist->AutoPlaylistIdL(EMPXMostPlayedPlaylist));
       
  2943 
       
  2944     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, plId, EMPXItemModified,
       
  2945         EMPXSong, KDBPluginUid, plId);
       
  2946 
       
  2947     // Force the deprecated ID attribute
       
  2948     aItemChangedMessages[aItemChangedMessages.Count() - 1]->
       
  2949         SetTObjectValueL<TMPXItemId>(KMPXMessageMediaDeprecatedId, plId);
       
  2950     }
       
  2951 
       
  2952 // ----------------------------------------------------------------------------------------------------------
       
  2953 // CMPXDbHandler::HandlePlaybackTimeModifiedL
       
  2954 // ----------------------------------------------------------------------------------------------------------
       
  2955 //
       
  2956 void CMPXDbHandler::HandlePlaybackTimeModifiedL(
       
  2957     CMPXMessageArray& aItemChangedMessages)
       
  2958     {
       
  2959     MPX_FUNC("CMPXDbHandler::HandlePlaybackTimeModifiedL");
       
  2960 
       
  2961     TUint32 plId(iAutoPlaylist->AutoPlaylistIdL(EMPXRecentlyPlayedPlaylist));
       
  2962 
       
  2963     MPXDbCommonUtil::AddItemChangedMessageL(aItemChangedMessages, plId, EMPXItemModified,
       
  2964         EMPXSong, KDBPluginUid, plId);
       
  2965 
       
  2966     // Force the deprecated ID attribute
       
  2967     aItemChangedMessages[aItemChangedMessages.Count() - 1]->
       
  2968         SetTObjectValueL<TMPXItemId>(KMPXMessageMediaDeprecatedId, plId);
       
  2969     }
       
  2970 
       
  2971 
       
  2972 // ---------------------------------------------------------------------------
       
  2973 // CMPXDbHandler::IsRemoteDrive
       
  2974 // ---------------------------------------------------------------------------
       
  2975 //
       
  2976 TBool CMPXDbHandler::IsRemoteDrive(TDriveNumber aDrive)
       
  2977     {
       
  2978     return iDbManager->IsRemoteDrive(aDrive);
       
  2979     }
       
  2980 
       
  2981 TInt CMPXDbHandler::HandlePlaylistDurationL(TUint32 aPlaylistId)
       
  2982 	{
       
  2983 	return GetPlaylistDurationL(aPlaylistId);
       
  2984 	}
       
  2985 void CMPXDbHandler::HandlePlaylistInfoL(
       
  2986     TUint32 aPlaylistId, 
       
  2987     TInt& aCount, 
       
  2988     TInt& aDuration)
       
  2989     {
       
  2990     MPX_FUNC("CMPXDbHandler::HandlePlaylistInfoL");
       
  2991     MPX_DEBUG2("CMPXDbHandler::HandlePlaylistInfoL(0x%x)", aPlaylistId);
       
  2992 
       
  2993     RArray<TMPXAttribute> attributes;
       
  2994     CleanupClosePushL(attributes);
       
  2995     attributes.AppendL(KMPXMediaGeneralId);    
       
  2996     attributes.AppendL(TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralDuration));
       
  2997 
       
  2998     CMPXMediaArray* mediaArray = CMPXMediaArray::NewL();
       
  2999     CleanupStack::PushL(mediaArray);    
       
  3000     
       
  3001     GetPlaylistSongsL(aPlaylistId, attributes.Array(), *mediaArray);
       
  3002     
       
  3003     aCount = mediaArray->Count();
       
  3004     for (TInt index = 0; index < aCount; ++index)
       
  3005         {
       
  3006         CMPXMedia* media((*mediaArray)[index]);
       
  3007         if (media->IsSupported(KMPXMediaGeneralDuration))
       
  3008             {
       
  3009             aDuration += media->ValueTObjectL<TInt>(KMPXMediaGeneralDuration);
       
  3010             }
       
  3011         }
       
  3012 
       
  3013     CleanupStack::PopAndDestroy(mediaArray);
       
  3014     CleanupStack::PopAndDestroy(&attributes);        
       
  3015     }
       
  3016 
       
  3017 TInt CMPXDbHandler::HandleGetAlbumsCountForArtistL(TUint32 aArtistId)
       
  3018 	{
       
  3019 	return iDbAlbum->GetAlbumsCountForArtistL(aArtistId);
       
  3020 	}
       
  3021 
       
  3022 TBool CMPXDbHandler::HandleIsUnknownArtistL(TUint32 aArtistId)
       
  3023     {
       
  3024     return iDbArtist->IsUnknownArtistL(aArtistId);
       
  3025     }
       
  3026 
       
  3027 TUint32 CMPXDbHandler::HandleArtistForAlbumL(const TUint32 aAlbumId)
       
  3028     {
       
  3029     return iDbMusic->ArtistForAlbumL(aAlbumId);
       
  3030     }
       
  3031 // End of file