mpserviceplugins/mpxsqlitedbhgplugin/src/mpxdbplugin.cpp
changeset 22 ecf06a08d4d9
child 25 3ec52facab4d
equal deleted inserted replaced
20:82baf59ce8dd 22:ecf06a08d4d9
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Implementation of collection DB Plugin interface
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <e32cmn.h>
       
    21 #include <StringLoader.h>
       
    22 #include <bautils.h>
       
    23 #include <data_caging_path_literals.hrh>
       
    24 
       
    25 #include <mpxcmn.h>
       
    26 #include <mpxuser.h>
       
    27 #include <mpxcollectionpluginobserver.h>
       
    28 #include <mpxmediacontainerdefs.h>
       
    29 #include <mpxmediamusicdefs.h>
       
    30 #include <mpxmediaaudiodefs.h>
       
    31 #include <mpxmediacollectiondetaildefs.h>
       
    32 #include <mpxcommandgeneraldefs.h>
       
    33 #include <mpxmessagegeneraldefs.h>
       
    34 #include <mpxmessagecontainerdefs.h>
       
    35 #include <mpxcollectioncommanddefs.h>
       
    36 #include <mpxcollectionmessagedefs.h>
       
    37 #include <mpxincrementalopendefs.h>
       
    38 #include <mpxcollectionopenlresultdef.h>
       
    39 #include <mpxmedia.h>
       
    40 #include <mpxmediaarray.h>
       
    41 #include <mpxdrmmediautility.h>
       
    42 #include <mpxmediadrmdefs.h>
       
    43 #include <mpxlog.h>
       
    44 #include <mpxcollectiondbhgres.rsg>
       
    45 #include <centralrepository.h>
       
    46 
       
    47 #ifdef RD_MULTIPLE_DRIVE
       
    48 #include <driveinfo.h>
       
    49 #endif //RD_MULTIPLE_DRIVE
       
    50 
       
    51 #include "mpxresource.h"
       
    52 #include "mpxdbcommondef.h"
       
    53 #include "mpxdbcommonutil.h"
       
    54 
       
    55 #include "mpxdbhandler.h"
       
    56 #include "mpxdbutil.h"
       
    57 #include "mpxcollectiondbdef.h"
       
    58 #include "mpxdbplugin.h"
       
    59 
       
    60 // CONSTANTS
       
    61 const TInt KFirstFetchCount = 400;
       
    62 
       
    63 const TUid KCRUIDMusicPlayerFeatures = { 0x101FFCD0 };
       
    64 const TInt KMusicPlayerFeatures = 1;
       
    65 const TInt KDisablePodcasting = 0x08;
       
    66 
       
    67 const TInt KIncrementalDeleteCount = 400;
       
    68 
       
    69 const TInt KSQLErrGeneral = -311; // SQL General error. Don't want to include sql header here
       
    70 // ============================ MEMBER FUNCTIONS ==============================
       
    71 
       
    72 // ----------------------------------------------------------------------------
       
    73 // Two-phased constructor.
       
    74 // ----------------------------------------------------------------------------
       
    75 //
       
    76 CMPXDbPlugin* CMPXDbPlugin::NewL(
       
    77     TAny* /*aInitParams*/)
       
    78     {
       
    79     MPX_FUNC("CMPXDbPlugin::NewL");
       
    80 
       
    81     CMPXDbPlugin* self = new (ELeave) CMPXDbPlugin();
       
    82     CleanupStack::PushL (self);
       
    83     self->ConstructL ();
       
    84     CleanupStack::Pop (self);
       
    85     return self;
       
    86     }
       
    87 
       
    88 // ----------------------------------------------------------------------------
       
    89 // Destructor.
       
    90 // ----------------------------------------------------------------------------
       
    91 //
       
    92 CMPXDbPlugin::~CMPXDbPlugin()
       
    93     {
       
    94     MPX_FUNC("CMPXDbPlugin::~CMPXDbPlugin");
       
    95 
       
    96     iSelections.Reset();
       
    97     iSelections.Close();
       
    98     iFs.Close();
       
    99     delete iDbHandler;
       
   100     delete iDrmMediaUtility;
       
   101     if (iResource)
       
   102         {
       
   103         iResource->Release();
       
   104         }
       
   105     iMusicLibraryMenuIds.Close();
       
   106     delete iMusicLibraryMenuTitles;
       
   107     delete iMusicLibraryTitles;
       
   108     delete iAllSongsForArtistTitle;
       
   109     delete iMusicMenuTitle;
       
   110 
       
   111     if (iActiveTask)
       
   112         {
       
   113         iActiveTask->Cancel();
       
   114         delete iActiveTask;
       
   115         }
       
   116     }
       
   117 
       
   118 // ----------------------------------------------------------------------------
       
   119 // Constructor.
       
   120 // ----------------------------------------------------------------------------
       
   121 //
       
   122 CMPXDbPlugin::CMPXDbPlugin()
       
   123     {
       
   124     MPX_FUNC("CMPXDbPlugin::CMPXDbPlugin");
       
   125     }
       
   126 
       
   127 // ----------------------------------------------------------------------------
       
   128 // Symbian 2nd phase constructor can leave.
       
   129 // ----------------------------------------------------------------------------
       
   130 //
       
   131 void CMPXDbPlugin::ConstructL()
       
   132     {
       
   133     MPX_FUNC("CMPXDbPlugin::ConstructL");
       
   134     iFirstDeleteStep = ETrue;
       
   135     User::LeaveIfError(iFs.Connect());
       
   136     iDrmMediaUtility = CMPXDrmMediaUtility::NewL();
       
   137 
       
   138     TParse parse;
       
   139     parse.Set( KMPXCollectionDbResourceFile, &KDC_APP_RESOURCE_DIR, NULL );
       
   140     TFileName resFile(parse.FullName());
       
   141     User::LeaveIfError(MPXUser::CompleteWithDllPath(resFile));
       
   142     BaflUtils::NearestLanguageFile(iFs, resFile);
       
   143     iResource = CMPXResource::NewL(resFile);
       
   144 
       
   145     iDbHandler = CMPXDbHandler::NewL(iFs, *iResource);
       
   146     iMusicLibraryMenuTitles = iResource->ReadMenuArrayL(R_MC_MENU_ITEMS_ARRAY, iMusicLibraryMenuIds);
       
   147     iMusicLibraryTitles = iResource->ReadMenuArrayL(R_MC_TITLE_ITEMS_ARRAY, iMusicLibraryMenuIds );
       
   148     iAllSongsForArtistTitle = iResource->ReadHBufCL(R_MC_ALL_SONGS_FOR_ARTIST);
       
   149 
       
   150 #ifdef __ENABLE_MUSIC_TEXT_ALIGNMENT
       
   151     iMusicMenuTitle = iResource->ReadHBufCL(R_MPX_QTN_MP_TITLE_MY_MUSIC_MENU_NSERIES);
       
   152 #else
       
   153     iMusicMenuTitle = iResource->ReadHBufCL(R_MPX_QTN_MUS_TITLE_MUSIC_MENU);
       
   154 #endif // __ENABLE_MUSIC_TEXT_ALIGNMENT
       
   155 
       
   156     iActiveTask = CMPXDbActiveTask::NewL(*this);
       
   157 
       
   158     CRepository* cenrep(NULL);
       
   159     TRAPD( err, cenrep = CRepository::NewL( KCRUIDMusicPlayerFeatures ) );
       
   160     if( err == KErrNone )
       
   161         {
       
   162         TInt val(0);
       
   163         cenrep->Get( KMusicPlayerFeatures, val );
       
   164         iDisablePodcasting = val&KDisablePodcasting ? ETrue:EFalse;
       
   165         delete cenrep;
       
   166         }
       
   167     else
       
   168         {
       
   169         iDisablePodcasting = EFalse;
       
   170         }
       
   171     iAllSongsValid = ETrue;
       
   172     }
       
   173 
       
   174 // ----------------------------------------------------------------------------
       
   175 // Navigates to the given path
       
   176 // ----------------------------------------------------------------------------
       
   177 //
       
   178 void CMPXDbPlugin::OpenL(
       
   179     const CMPXCollectionPath& aPath,
       
   180     const TArray<TMPXAttribute>& /*aAttrs*/,
       
   181     CMPXFilter* aFilter)
       
   182     {
       
   183     MPX_FUNC("CMPXDbPlugin::OpenL");
       
   184     MPX_DEBUG_PATH(aPath);
       
   185     //Create a path object to be returned.
       
   186     CMPXCollectionPath* path = CMPXCollectionPath::NewL(aPath);
       
   187     CleanupStack::PushL(path);
       
   188     RArray<TMPXAttribute> openAttrs;
       
   189     CleanupClosePushL(openAttrs);
       
   190 
       
   191     RArray<TInt> supportedIds;
       
   192     CleanupClosePushL(supportedIds);
       
   193 
       
   194     // Replace the attributes requested by the client with the ones below.
       
   195     // This will eventually have to be fixed
       
   196     SetAttributesL(aPath, openAttrs, supportedIds);
       
   197 
       
   198     CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
       
   199     CleanupStack::PopAndDestroy(&supportedIds);
       
   200     CleanupStack::PushL(entries);
       
   201     //Add returned path into media
       
   202     entries->SetTObjectValueL<TInt>(KMPXMediaGeneralValue, (TInt)path);
       
   203 
       
   204     TInt error(KErrNone);
       
   205     TBool isASong(EFalse);
       
   206     CMPXCollectionPath* newPath(NULL);
       
   207 
       
   208     // Make sure we handle open the correct open mode
       
   209     //
       
   210     TMPXOpenMode openmode = aPath.OpenNextMode();
       
   211     switch (openmode)
       
   212         {
       
   213         case EMPXOpenGroupOrPlaylist:
       
   214             {
       
   215             // Open By Path
       
   216             MPX_TRAP(error, isASong = DoOpenL(aPath, openAttrs.Array(), *entries, aFilter));
       
   217             break;
       
   218             }
       
   219 
       
   220         case EMPXOpenPlaylistOnly:
       
   221             {
       
   222             if (aPath.Count() > 0)
       
   223                 {
       
   224                 // Try to open
       
   225                 MPX_TRAP(error, newPath = DoOpenPlaylistL(aPath, openAttrs.Array()));
       
   226                 CleanupStack::PushL(newPath);
       
   227                 isASong = ETrue;
       
   228                 }
       
   229             else // no items
       
   230                 {
       
   231                 MPX_TRAP(error, isASong = DoOpenL(aPath, openAttrs.Array(), *entries, aFilter));
       
   232                 }
       
   233 
       
   234             break;
       
   235             }
       
   236 
       
   237         default:
       
   238             // do nothing
       
   239             break;
       
   240         }
       
   241 
       
   242     // generate the callback
       
   243     if (isASong )
       
   244         {
       
   245         if (openmode == EMPXOpenGroupOrPlaylist)
       
   246             {
       
   247             iObs->HandleOpen(const_cast<CMPXCollectionPath*>(&aPath), error);
       
   248             }
       
   249         else  // openmode == EMPXOpenPlaylistOnly
       
   250             {
       
   251             iObs->HandleOpen(newPath, error);
       
   252             }
       
   253         }
       
   254     else
       
   255         {
       
   256         entries->SetCObjectValueL(KMPXMediaGeneralContainerPath,
       
   257             const_cast<CMPXCollectionPath*>(&aPath));
       
   258         entries->Delete(KMPXMediaGeneralValue);
       
   259         iObs->HandleOpen(entries, path, error);
       
   260         }
       
   261 
       
   262     if (newPath)
       
   263         {
       
   264         CleanupStack::PopAndDestroy(newPath);
       
   265         }
       
   266 
       
   267     CleanupStack::PopAndDestroy(entries);
       
   268     CleanupStack::PopAndDestroy(&openAttrs);
       
   269     CleanupStack::PopAndDestroy(path);
       
   270     }
       
   271 
       
   272 // ----------------------------------------------------------------------------
       
   273 // Get the extended properties of the current file (async)
       
   274 // ----------------------------------------------------------------------------
       
   275 //
       
   276 void CMPXDbPlugin::MediaL(
       
   277     const CMPXCollectionPath& aPath,
       
   278     const TArray<TMPXAttribute>& aAttrs,
       
   279     const TArray<TCapability>& /*aCaps*/,
       
   280     CMPXAttributeSpecs* /*aSpecs*/)
       
   281     {
       
   282     MPX_FUNC("CMPXDbPlugin::MediaL");
       
   283     MPX_DEBUG_PATH(aPath);
       
   284 
       
   285     RArray<TInt> supportedIds;
       
   286     CleanupClosePushL(supportedIds);
       
   287     if (aPath.Selection().Count())
       
   288         {
       
   289         // it's a container if there are multiple selection, else it's not a container
       
   290         supportedIds.AppendL(KMPXMediaIdContainer);
       
   291         }
       
   292     MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
       
   293 
       
   294     CMPXMedia* entries = CMPXMedia::NewL(supportedIds.Array());
       
   295     CleanupStack::PopAndDestroy(&supportedIds);
       
   296     CleanupStack::PushL(entries);
       
   297 
       
   298     DoMediaL(aPath, aAttrs, *entries);
       
   299 
       
   300     // Also fetch collection details and set the path if required
       
   301     DoHandleOtherMediaAttributesL(aAttrs, aPath, *entries);
       
   302 
       
   303     iObs->HandleMedia(entries, KErrNone);
       
   304     CleanupStack::PopAndDestroy(entries);
       
   305     }
       
   306 
       
   307 // ----------------------------------------------------------------------------
       
   308 // Cancel outstanding request
       
   309 // ----------------------------------------------------------------------------
       
   310 //
       
   311 void CMPXDbPlugin::CancelRequest()
       
   312     {
       
   313     MPX_FUNC("CMPXDbPlugin::CancelRequest");
       
   314     iActiveTask->Cancel();
       
   315     }
       
   316 
       
   317 // ----------------------------------------------------------------------------
       
   318 // Executes the given command on the collection
       
   319 // ----------------------------------------------------------------------------
       
   320 //
       
   321 void CMPXDbPlugin::CommandL(
       
   322     TMPXCollectionCommand aCmd,
       
   323     TInt aArg /* = 0 */)
       
   324     {
       
   325     MPX_FUNC("CMPXDbPlugin::CommandL");
       
   326     MPX_DEBUG2("CMPXDbPlugin::CommandL %d", aCmd);
       
   327     iAllSongsValid = ETrue;
       
   328     switch (aCmd)
       
   329         {
       
   330         case EMcCmdRemoveAll:
       
   331             {
       
   332             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcCmdRemoveAll");
       
   333             // Remove EVERYthing from the collection
       
   334             iDbHandler->RemoveEntireCollectionL();
       
   335             break;
       
   336             }
       
   337         case EMcCmdClose:
       
   338         case EMcCloseCollection:
       
   339             {
       
   340             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcCloseCollection");
       
   341             // Close the specified database
       
   342             TRAP_IGNORE(iDbHandler->PreCloseCollectionL());
       
   343  #ifdef RD_MULTIPLE_DRIVE
       
   344             MPX_DEBUG1("Multiple drives closing databases");
       
   345             if ( aArg <0)
       
   346                 {
       
   347                 DriveInfo::TDriveArray driveArray;
       
   348                 User::LeaveIfError ( DriveInfo::GetUserVisibleDrives( iFs, driveArray));
       
   349                 TInt count( driveArray.Count ());
       
   350                 for (TInt i=0; i<count; ++i)
       
   351                     {
       
   352                     MPX_DEBUG2("At drive %i", driveArray[i]);
       
   353                     if (( driveArray[i] != EDriveC) && (!iDbHandler->IsRemoteDrive(static_cast<TDriveNumber>(driveArray[i])))) 
       
   354                         {
       
   355                         MPX_DEBUG2("Closing database %i", driveArray[i]);
       
   356                         TRAP_IGNORE( iDbHandler->CloseDatabaseL( driveArray[i] ) );
       
   357                         }
       
   358                     }
       
   359                 }
       
   360             else
       
   361                 {
       
   362                 iDbHandler->CloseDatabaseL(aArg);
       
   363                 }
       
   364  #else
       
   365             iDbHandler->CloseDatabaseL(aArg);
       
   366  #endif // RD_MULTIPLE_DRIVE
       
   367             iDbHandler->CollectionClosed();
       
   368             break;
       
   369             }
       
   370         case EMcReOpenCollection:
       
   371             {
       
   372             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcReOpenCollection");
       
   373             // Open the specified database
       
   374 #ifdef RD_MULTIPLE_DRIVE
       
   375             MPX_DEBUG1("Multiple drives opening databases");
       
   376             DriveInfo::TDriveArray driveArray;
       
   377             User::LeaveIfError( DriveInfo::GetUserVisibleDrives( iFs, driveArray ) );
       
   378             TInt count( driveArray.Count() );
       
   379             for( TInt i=0; i<count; ++i )
       
   380                 {
       
   381                 MPX_DEBUG2("At drive %i", driveArray[i]);
       
   382                 if( (driveArray[i] != EDriveC)  && (!iDbHandler->IsRemoteDrive(static_cast<TDriveNumber>(driveArray[i])))) 
       
   383                     {
       
   384                     TUint driveStatus(0);
       
   385                     User::LeaveIfError( DriveInfo::GetDriveStatus(
       
   386                         iFs, driveArray[i], driveStatus ) );
       
   387                     if( driveStatus & DriveInfo::EDrivePresent )
       
   388                         {
       
   389                         MPX_DEBUG2("Opening database %i", driveArray[i]);
       
   390                         TRAP_IGNORE( iDbHandler->OpenDatabaseL( driveArray[i] ) );
       
   391                         }
       
   392                     }
       
   393                 }
       
   394 #else
       
   395             iDbHandler->OpenDatabaseL(aArg);
       
   396 #endif // RD_MULTIPLE_DRIVE
       
   397             TRAP_IGNORE(iDbHandler->CollectionOpenedL());
       
   398             break;
       
   399             }
       
   400         case EMcRefreshStarted:
       
   401             {
       
   402             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcRefreshStarted");
       
   403             iDbHandler->CheckDiskSpaceOnDrivesL();
       
   404             // ask the handler to start a transaction
       
   405             iDbHandler->RefreshStartL();
       
   406             iRefreshing=ETrue;
       
   407             break;
       
   408             }
       
   409         case EMcRefreshEnded:
       
   410             {
       
   411             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcRefreshEnded");
       
   412             iDbHandler->CheckDiskSpaceOnDrivesL();
       
   413             // ask the handler to finalize the transaction
       
   414             iDbHandler->RefreshEndL();
       
   415             iRefreshing=EFalse;
       
   416             break;
       
   417             }
       
   418          case EMcCmdReCreateDB:
       
   419             {
       
   420             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcCmdReCreateDB");
       
   421             // Recreate all databases
       
   422             iDbHandler->ReCreateDatabasesL();
       
   423             break;
       
   424             }
       
   425          case EMcCmdDbCorrupted:
       
   426             {
       
   427             MPX_DEBUG1("CMPXDbPlugin::CommandL - EMcCmdDbCorrupted");
       
   428             iDbHandler->SetDBCorruptedL(ETrue);
       
   429             break;
       
   430             }
       
   431         case EMcCmdRefresh:
       
   432         case EMcCmdCollectionInit:
       
   433         case EMcCmdCollectionResyn:
       
   434             {
       
   435             // deprecated
       
   436             break;
       
   437             }
       
   438         case EMcCmdMtpStart:
       
   439             iDbHandler->CheckDiskSpaceOnDrivesL();
       
   440             iMtpInUse = ETrue;
       
   441             iDbHandler->MtpStartL();            
       
   442             break;
       
   443         case EMcCmdMtpEnd:
       
   444             iDbHandler->CheckDiskSpaceOnDrivesL();
       
   445             iMtpInUse = EFalse;
       
   446             iDbHandler->MtpEndL();            
       
   447             break;
       
   448          default:
       
   449             {
       
   450             User::Leave(KErrNotSupported);
       
   451             }
       
   452         }
       
   453     }
       
   454 
       
   455 // ----------------------------------------------------------------------------
       
   456 // Executes the given command on the collection
       
   457 // ----------------------------------------------------------------------------
       
   458 //
       
   459 void CMPXDbPlugin::CommandL(
       
   460     CMPXCommand& aCmd)
       
   461     {
       
   462     MPX_FUNC("CMPXDbPlugin::CommandL");
       
   463 
       
   464     if (!aCmd.IsSupported(KMPXCommandGeneralId))
       
   465         {
       
   466         User::Leave(KErrArgument);
       
   467         }
       
   468 
       
   469     TMPXCommandId commandId = aCmd.ValueTObjectL<TMPXCommandId>(KMPXCommandGeneralId);
       
   470 
       
   471     TBool syncOp(EFalse);
       
   472     if (aCmd.IsSupported(KMPXCommandGeneralDoSync))
       
   473         {
       
   474         syncOp = aCmd.ValueTObjectL<TBool>(KMPXCommandGeneralDoSync);
       
   475         }
       
   476 
       
   477     // Handle this operation synchronously or asynchronously
       
   478     //
       
   479     if (!syncOp)
       
   480         {
       
   481         iActiveTask->StartL(commandId, aCmd);
       
   482         }
       
   483     else  // Sync operation
       
   484         {
       
   485         switch (commandId)
       
   486             {
       
   487             case KMPXCommandIdCollectionRetrieveUriForDeletion:
       
   488                 {
       
   489                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionRetrieveUriForDeletion");
       
   490                 DoRetrieveUriForDeletionL(aCmd);
       
   491                 break;
       
   492                 }
       
   493             case KMPXCommandIdCollectionRemove:
       
   494                 {
       
   495                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionRemove");
       
   496                 if ( !iDbHandler->InTransaction() )
       
   497                     {
       
   498                     iDbHandler->BeginTransactionL();
       
   499                     }
       
   500 
       
   501                 if (iFirstDeleteStep )
       
   502                     {
       
   503                     iFirstDeleteStep = EFalse;
       
   504                     }
       
   505                 DoRemovePathL(aCmd);
       
   506                 break;
       
   507                 }
       
   508             case KMPXCommandIdCollectionRemoveMedia:
       
   509                 {
       
   510                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionRemoveMedia");
       
   511                 DoRemoveMediaL(aCmd);
       
   512                 break;
       
   513                 }
       
   514             case KMPXCommandIdCollectionCleanupDeletedMedias:
       
   515                 {
       
   516                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionCleanupDeletedMedias");
       
   517                 CleanupDeletedRecordsL(aCmd);
       
   518                 break;
       
   519                 }
       
   520             case KMPXCommandIdCollectionAdd:
       
   521                 {
       
   522                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectioAdd");
       
   523                 CMPXMedia* media = aCmd.Value<CMPXMedia>(KMPXCommandColAddMedia);
       
   524                 User::LeaveIfNull( media );
       
   525                 TUint32 id(DoAddL(*media));
       
   526                 aCmd.SetTObjectValueL<TMPXItemId>(KMPXCommandColAddRtnId, id);
       
   527                 break;
       
   528                 }
       
   529             case KMPXCommandIdCollectionSet:
       
   530                 {
       
   531                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionSet");
       
   532                 CMPXMedia* media = aCmd.Value<CMPXMedia>(KMPXCommandColSetMedia);
       
   533                 User::LeaveIfNull( media );
       
   534                 DoSetL(*media);
       
   535                 break;
       
   536                 }
       
   537             case KMPXCommandIdCollectionCompleteDelete:
       
   538                 {
       
   539                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdCollectionCompleteDelete");
       
   540                 DoHandleDeleteCompleteL(aCmd);
       
   541                 break;
       
   542                 }
       
   543             case KMPXCommandIdReorderPlaylist:
       
   544                 {
       
   545                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdReorderPlaylist");
       
   546                 DoReorderPlaylistL(aCmd);
       
   547                 break;
       
   548                 }
       
   549             case KMPXCommandIdUpdateRefreshTime:
       
   550                 {
       
   551                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdUpdateRefreshTime");
       
   552                 TTime curTime;
       
   553                 curTime.HomeTime();
       
   554                 iDbHandler->SetLastRefreshedTimeL(curTime);
       
   555                 break;
       
   556                 }
       
   557             case KMPXCommandCollectionGetCount:
       
   558                 {
       
   559                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandCollectionGetCount");
       
   560                 DoGetCollectionCountL(aCmd);
       
   561                 break;
       
   562                 }
       
   563             case KMPXCommandCollectionGetURIs:
       
   564                 {
       
   565                 MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandCollectionGetURIs");
       
   566                 DoGetCollectionUriL(aCmd);
       
   567                 break;
       
   568                 }
       
   569             default:
       
   570                 {
       
   571                 User::Leave(KErrNotSupported);
       
   572                 }
       
   573             }
       
   574         }
       
   575     }
       
   576 
       
   577 // ----------------------------------------------------------------------------
       
   578 // Adds an item (song or playlist) to the collection
       
   579 // ----------------------------------------------------------------------------
       
   580 //
       
   581 void CMPXDbPlugin::AddL(
       
   582     const CMPXMedia& aMedia)
       
   583     {
       
   584     MPX_FUNC("CMPXDbPlugin::AddL");
       
   585     DoAddL(aMedia);
       
   586     }
       
   587 
       
   588 // ----------------------------------------------------------------------------
       
   589 // Remove an item from the collection database using the given path
       
   590 // ----------------------------------------------------------------------------
       
   591 //
       
   592 void CMPXDbPlugin::RemoveL(
       
   593     const CMPXCollectionPath& aPath)
       
   594     {
       
   595     MPX_FUNC("CMPXDbPlugin::RemoveL(by path)");
       
   596     MPX_DEBUG_PATH(aPath);
       
   597 
       
   598     CMPXMessageArray* msgAry = CMPXMessageArray::NewL();
       
   599     CleanupStack::PushL(msgAry);
       
   600 
       
   601     // Return file path for deleted item(s)
       
   602     CDesCArray* fp = DoRemoveL(aPath, *msgAry);
       
   603 
       
   604     iObs->HandleRemove(*fp, KErrNone);
       
   605     delete fp;
       
   606 
       
   607     // Send Change Messages
       
   608     iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
   609     DoHandleChangeL(msgAry);
       
   610     CleanupStack::PopAndDestroy(msgAry);
       
   611     }
       
   612 
       
   613 // ----------------------------------------------------------------------------
       
   614 // Remove an item from the collection database using the given media properties
       
   615 // ----------------------------------------------------------------------------
       
   616 //
       
   617 void CMPXDbPlugin::RemoveL(
       
   618     const CMPXMedia& aMedia)
       
   619     {
       
   620     MPX_FUNC("CMPXDbPlugin::RemoveL(by media)");
       
   621     DoRemoveL(aMedia, EFalse);
       
   622     }
       
   623 
       
   624 // ----------------------------------------------------------------------------
       
   625 // Sets/updates the media for an item in the collection
       
   626 // DEPRECATED for week 18
       
   627 // ----------------------------------------------------------------------------
       
   628 //
       
   629 void CMPXDbPlugin::SetL(
       
   630     const CMPXMedia& aMedia)
       
   631     {
       
   632     MPX_FUNC("CMPXDbPlugin::SetL");
       
   633     DoSetL(aMedia);
       
   634     }
       
   635 
       
   636 // ----------------------------------------------------------------------------
       
   637 // Find the items matching the media specifications
       
   638 // ----------------------------------------------------------------------------
       
   639 //
       
   640 void CMPXDbPlugin::FindAllL(
       
   641     const CMPXMedia& aCriteria,
       
   642     const TArray<TMPXAttribute>& aAttrs)
       
   643     {
       
   644     MPX_FUNC("CMPXDbPlugin::FindAllL");
       
   645 
       
   646     CMPXMedia* entries = FindAllSyncL(aCriteria, aAttrs);
       
   647 
       
   648     // notify client. if FindAllL leaves, framework will notify client of the error
       
   649     iObs->HandleFindAll(entries, KErrNone);
       
   650     delete entries;
       
   651     }
       
   652 
       
   653 // ----------------------------------------------------------------------------
       
   654 // Find the items matching the media specifications
       
   655 // ----------------------------------------------------------------------------
       
   656 //
       
   657 CMPXMedia* CMPXDbPlugin::FindAllSyncL(
       
   658     const CMPXMedia& aCriteria,
       
   659     const TArray<TMPXAttribute>& aAttrs)
       
   660     {
       
   661     MPX_FUNC("CMPXDbPlugin::FindAllSyncL");
       
   662 
       
   663     CMPXMedia* entries = iDbHandler->FindAllLC(aCriteria, aAttrs);
       
   664 
       
   665     if (entries)
       
   666         {
       
   667         CMPXMediaArray* ary = entries->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
   668         User::LeaveIfNull( ary );
       
   669         DoSetDrmForArrayL( *ary, aAttrs );
       
   670         }
       
   671 
       
   672     CleanupStack::Pop(entries);
       
   673     return entries;
       
   674     }
       
   675 
       
   676 // ----------------------------------------------------------------------------
       
   677 // Get the list of supported capabilities
       
   678 // ----------------------------------------------------------------------------
       
   679 //
       
   680 TCollectionCapability CMPXDbPlugin::GetCapabilities()
       
   681     {
       
   682     // This one supports simple search
       
   683     return EMcSearch;
       
   684     }
       
   685 
       
   686 // ----------------------------------------------------------------------------
       
   687 // Get the list of supported capabilities
       
   688 // ----------------------------------------------------------------------------
       
   689 //
       
   690 TBool CMPXDbPlugin::HandleStepL()
       
   691     {
       
   692     MPX_FUNC("CMPXDbPlugin::HandleStepL");
       
   693 
       
   694     TBool done(ETrue);
       
   695 
       
   696     switch (iActiveTask->GetTask())
       
   697         {
       
   698         case KMPXCommandIdCollectionSet:
       
   699             {
       
   700             done = DoSetAsyncL();
       
   701             break;
       
   702             }
       
   703         case KMPXCommandIdCollectionAdd:
       
   704             {
       
   705             done = DoAddAsyncL();
       
   706             break;
       
   707             }
       
   708         case KMPXCommandIdCollectionRemove:
       
   709             {
       
   710             DoRemovePathL(iActiveTask->GetCommand());
       
   711             done = ETrue;
       
   712             break;
       
   713             }
       
   714         case KMPXCommandIdCollectionRemoveMedia:
       
   715             {
       
   716             DoRemoveMediaL(iActiveTask->GetCommand());
       
   717             done = ETrue;
       
   718             break;
       
   719             }
       
   720         case KMPXCommandIdCollectionRetrieveUriForDeletion:
       
   721             {
       
   722             DoRetrieveUriForDeletionL(iActiveTask->GetCommand());
       
   723             done = ETrue;
       
   724             break;
       
   725             }
       
   726         case KMPXCommandIdCollectionCleanupDeletedMedias:
       
   727             {
       
   728             CleanupDeletedRecordsL(iActiveTask->GetCommand());
       
   729             done = ETrue;
       
   730             break;
       
   731             }
       
   732         case KMPXCommandIdCollectionCompleteDelete:
       
   733             {
       
   734             DoHandleDeleteCompleteL( iActiveTask->GetCommand() );
       
   735             break;
       
   736             }
       
   737         case KMPXCommandIdUpdateRefreshTime:
       
   738             {
       
   739             MPX_DEBUG1("CMPXDbPlugin::CommandL - KMPXCommandIdUpdateRefreshTime");
       
   740             TTime curTime;
       
   741             curTime.HomeTime();
       
   742             iDbHandler->SetLastRefreshedTimeL(curTime);
       
   743             break;
       
   744             }
       
   745         case KMPXCommandIdIncrementalOpenL:
       
   746             {
       
   747             DoIncrementalOpenL( iActiveTask->GetCommand() );
       
   748             done = ETrue;
       
   749             break;
       
   750             }
       
   751         default:
       
   752             {
       
   753             // Should never happen!
       
   754             ASSERT(0);
       
   755             break;
       
   756             }
       
   757         }
       
   758     return done;
       
   759     }
       
   760 
       
   761 // ----------------------------------------------------------------------------
       
   762 // Handler for async operations completed
       
   763 // ----------------------------------------------------------------------------
       
   764 //
       
   765 void CMPXDbPlugin::HandleOperationCompleted(
       
   766     TInt aErr)
       
   767     {
       
   768     MPX_FUNC("CMPXDbPlugin::HandleOperationCompleted");
       
   769     TRAP_IGNORE(DoHandleOperationCompletedL(aErr));
       
   770     }
       
   771 
       
   772 // ----------------------------------------------------------------------------
       
   773 // Process the OpenL command
       
   774 // ----------------------------------------------------------------------------
       
   775 //
       
   776 TBool CMPXDbPlugin::DoOpenL(
       
   777     const CMPXCollectionPath& aPath,
       
   778     const TArray<TMPXAttribute>& aAttrs,
       
   779     CMPXMedia& aEntries,
       
   780     CMPXFilter* aFilter )
       
   781     {
       
   782     MPX_FUNC("CMPXDbPlugin::DoOpenL");
       
   783 
       
   784     TInt err( KErrNone );
       
   785     CMPXMediaArray* array = CMPXMediaArray::NewL();
       
   786     CleanupStack::PushL(array);
       
   787 
       
   788 //    TInt count(0);
       
   789     TInt levels(aPath.Levels());
       
   790     TBool isASong(EFalse);
       
   791 
       
   792 
       
   793 	if ( 1 == levels )
       
   794 	    {
       
   795 
       
   796 	    // Redirecting all open requests at level 1 to open albums 
       
   797 	    // due to UI changes that removed the library menu collection level.
       
   798         TInt acount = array->Count();
       
   799         MPX_DEBUG2(" array count11 [%d]", acount);
       
   800         
       
   801  		CMPXCollectionPath* path = CMPXCollectionPath::NewL(aPath);
       
   802 		CleanupStack::PushL( path );
       
   803 		
       
   804 		path->AppendL(3); // Albums
       
   805 		TInt whatLevel = path->Levels();
       
   806 
       
   807 		MPX_DEBUG_PATH(*path);
       
   808 		
       
   809 		aEntries.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, path->Id(whatLevel - 1) );
       
   810 		
       
   811       // Create a media which hold the pointer to the returned path
       
   812         if (aEntries.IsSupported(KMPXMediaGeneralValue))
       
   813             {
       
   814             MPX_DEBUG1(" pointer to the returned path ");
       
   815             CMPXMedia* pMedia = CMPXMedia::NewL();
       
   816             CleanupStack::PushL(pMedia);
       
   817             pMedia->SetTObjectValueL<TInt>(KMPXMediaGeneralValue,
       
   818                                           aEntries.ValueTObjectL<TInt>(KMPXMediaGeneralValue));
       
   819             array->AppendL(*pMedia);
       
   820             CleanupStack::PopAndDestroy(pMedia);
       
   821             }
       
   822 		
       
   823 	
       
   824         RArray<TMPXAttribute> openAttrs;
       
   825         CleanupClosePushL(openAttrs);
       
   826 
       
   827         RArray<TInt> supportedIds;
       
   828         CleanupClosePushL(supportedIds);
       
   829 
       
   830         SetAttributesL(*path, openAttrs, supportedIds);
       
   831         openAttrs.AppendL(KMPXMediaArrayContents);
       
   832         
       
   833         CleanupStack::PopAndDestroy(&supportedIds);
       
   834 		
       
   835 		if( iAllSongsValid )
       
   836 		    {
       
   837 		    isASong = DoOpenBrowseAlbumL( *path, openAttrs.Array(), aEntries, array );
       
   838 		    }
       
   839 		CleanupStack::PopAndDestroy(&openAttrs);
       
   840 		CleanupStack::PopAndDestroy( path );
       
   841 
       
   842         //Remove the first media
       
   843         if ( array->Count() &&
       
   844             (*array)[0]->IsSupported(KMPXMediaGeneralValue))
       
   845             {
       
   846             array->Remove(0);
       
   847             }
       
   848 	    }
       
   849     else if (levels >= 2)
       
   850         {
       
   851 	    aEntries.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aPath.Id(levels - 1));
       
   852         // Create a media which hold the pointer to the returned path
       
   853         if (aEntries.IsSupported(KMPXMediaGeneralValue))
       
   854             {
       
   855             CMPXMedia* pMedia = CMPXMedia::NewL();
       
   856             CleanupStack::PushL(pMedia);
       
   857             pMedia->SetTObjectValueL<TInt>(KMPXMediaGeneralValue,
       
   858                                           aEntries.ValueTObjectL<TInt>(KMPXMediaGeneralValue));
       
   859             array->AppendL(*pMedia);
       
   860             CleanupStack::PopAndDestroy(pMedia);
       
   861             MPX_ASSERT(array->Count()==1);
       
   862             }
       
   863 
       
   864         // check the browse type
       
   865         switch (aPath.Id(1).iId2)
       
   866             {
       
   867             case EBrowseAll:
       
   868                 {
       
   869                 TBool doIncremental(ETrue);
       
   870                 if( aFilter && aFilter->IsSupported( KMPXCollectionOpenLSupportsIncremental ) )
       
   871                     {
       
   872                     doIncremental =
       
   873                          aFilter->ValueTObjectL<TBool>(KMPXCollectionOpenLSupportsIncremental);
       
   874                     }
       
   875 
       
   876                 if( doIncremental )
       
   877                     {
       
   878                     TRAP( err, isASong = DoOpenIncrementalL( aPath, aAttrs, aEntries, array ) );
       
   879                     }
       
   880                 else
       
   881                     {
       
   882                     TRAP( err, isASong = DoOpenBrowseAllL(aPath, aAttrs, aEntries, array) );
       
   883                     }
       
   884                 break;
       
   885                 }
       
   886 
       
   887             case EBrowseArtist:
       
   888                 {
       
   889                 if( iAllSongsValid )
       
   890                     {
       
   891                     isASong = DoOpenBrowseArtistL( aPath, aAttrs, aEntries, array );
       
   892                     }
       
   893                 break;
       
   894                 }
       
   895 
       
   896             case EBrowseAlbum:
       
   897                 {
       
   898                 if( iAllSongsValid )
       
   899                     {
       
   900                     isASong = DoOpenBrowseAlbumL( aPath, aAttrs, aEntries, array );
       
   901                     }
       
   902                 break;
       
   903                 }
       
   904 
       
   905             case EBrowsePlaylist:
       
   906                 {
       
   907                 if( iAllSongsValid )
       
   908                     {
       
   909                     isASong = DoOpenBrowsePlaylistL(aPath, aAttrs, aEntries, array);
       
   910                     }
       
   911 
       
   912                 break;
       
   913                 }
       
   914 
       
   915             case EBrowseGenre:
       
   916                 {
       
   917                 if( iAllSongsValid )
       
   918                     {
       
   919                     isASong = DoOpenBrowseGenreL( aPath, aAttrs, aEntries, array );
       
   920                     }
       
   921                 break;
       
   922                 }
       
   923 
       
   924             case EBrowseComposer:
       
   925                 {
       
   926                 if( iAllSongsValid )
       
   927                     {
       
   928                     isASong = DoOpenBrowseComposerL( aPath, aAttrs, aEntries, array );
       
   929                     }
       
   930                 break;
       
   931                 }
       
   932 
       
   933             default:
       
   934                 {
       
   935                 User::Leave(KErrArgument);
       
   936                 }
       
   937             }
       
   938         //Remove the first media
       
   939         if ( array->Count() &&
       
   940             (*array)[0]->IsSupported(KMPXMediaGeneralValue))
       
   941             {
       
   942             array->Remove(0);
       
   943             }
       
   944         }
       
   945     else
       
   946         {
       
   947         User::Leave(KErrNotSupported);
       
   948         }
       
   949     aEntries.SetCObjectValueL(KMPXMediaArrayContents, array);
       
   950     aEntries.SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
   951 
       
   952     CleanupStack::PopAndDestroy(array);
       
   953 
       
   954     if( err == KSQLErrGeneral )
       
   955         {
       
   956         iAllSongsValid = EFalse;
       
   957         User::Leave( KErrDiskFull );
       
   958         }
       
   959     else if( err != KErrNone )
       
   960         {
       
   961         User::Leave( err );
       
   962         }
       
   963     return isASong;
       
   964     }
       
   965 
       
   966 
       
   967 // ----------------------------------------------------------------------------
       
   968 // CMPXDbPlugin::DoOpenIncrementalL
       
   969 // ----------------------------------------------------------------------------
       
   970 //
       
   971 TBool CMPXDbPlugin::DoOpenIncrementalL( const CMPXCollectionPath& aPath,  const TArray<TMPXAttribute>& aAttrs,
       
   972                                        CMPXMedia& aEntries, CMPXMediaArray* aArray)
       
   973     {
       
   974     TBool isASong(EFalse);
       
   975 
       
   976     TInt levels(aPath.Levels());
       
   977 
       
   978     if( levels == 2 )
       
   979         {
       
   980         // Remove the pPath dummy from the array
       
   981         TInt pPath = aEntries.ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
   982         aArray->Remove(0);
       
   983         CMPXCollectionPath* p = (CMPXCollectionPath*) pPath;
       
   984 
       
   985         RArray<TMPXItemId> ids;
       
   986         CleanupClosePushL( ids );
       
   987 
       
   988         iDbHandler->GetAllSongsLimitedL( aAttrs, *aArray, KFirstFetchCount );
       
   989 
       
   990         TInt c( aArray->Count() );
       
   991         for( TInt i=0; i<c; ++i )
       
   992             {
       
   993             TMPXItemId id = aArray->AtL(i)->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
       
   994             ids.Append( id );
       
   995             }
       
   996 
       
   997         // Rest are all blank items
       
   998         CMPXMedia* entry = CMPXMedia::NewL();
       
   999         CleanupStack::PushL(entry);
       
  1000         entry->SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXItem);
       
  1001         entry->SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, EMPXSong);
       
  1002         entry->SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, KMPXInvalidItemId );
       
  1003 
       
  1004         TInt count = iDbHandler->NumberOfItemsL(EMPXSong);
       
  1005         count-=c;
       
  1006         for( TInt i=0; i<count; ++i )
       
  1007             {
       
  1008             aArray->AppendL( *entry );
       
  1009             ids.Append( KMPXInvalidItemId );
       
  1010             }
       
  1011         CleanupStack::PopAndDestroy( entry );
       
  1012 
       
  1013         // Set the "Supportes incremental Command" flag
       
  1014         //
       
  1015         aEntries.SetTObjectValueL( KMPXCollectionOpenLSupportsIncremental, ETrue );
       
  1016 
       
  1017         TMPXOpenDataBlock block;
       
  1018         block.iOffset=KErrNotFound;
       
  1019         block.iSize=count;
       
  1020         aEntries.SetTObjectValueL<TMPXOpenDataBlock>( KMPXCollectionOpenLResultRange, block );
       
  1021 
       
  1022         SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXSong,
       
  1023                 iMusicLibraryTitles->MdcaPoint(EBrowseAll));
       
  1024 
       
  1025         p->AppendL(ids.Array());
       
  1026         CleanupStack::PopAndDestroy( &ids );
       
  1027         }
       
  1028     else if( levels == 3 )
       
  1029         {
       
  1030         iDbHandler->GetSongL(aPath.Id(levels - 1).iId2, aAttrs, *aArray);
       
  1031         isASong = ETrue;
       
  1032         }
       
  1033 
       
  1034 
       
  1035     return isASong;
       
  1036     }
       
  1037 
       
  1038 // ----------------------------------------------------------------------------
       
  1039 // Handles OpenL called for EBrowseAll
       
  1040 // ----------------------------------------------------------------------------
       
  1041 //
       
  1042 TBool CMPXDbPlugin::DoOpenBrowseAllL(
       
  1043     const CMPXCollectionPath& aPath,
       
  1044     const TArray<TMPXAttribute>& aAttrs,
       
  1045     CMPXMedia& aEntries,
       
  1046     CMPXMediaArray* aArray)
       
  1047     {
       
  1048     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseAllL");
       
  1049 
       
  1050     TInt levels(aPath.Levels());
       
  1051     switch (levels)
       
  1052        {
       
  1053        // All songs
       
  1054        case 2:
       
  1055             {
       
  1056             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAllL_All);
       
  1057 
       
  1058             iDbHandler->GetAllSongsL(aArray, aAttrs);
       
  1059             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXSong,
       
  1060                 iMusicLibraryTitles->MdcaPoint(EBrowseAll));
       
  1061 
       
  1062             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAllL_All);
       
  1063             break;
       
  1064             }
       
  1065 
       
  1066          // A Song in all songs
       
  1067          case 3:
       
  1068             {
       
  1069             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAllL_Song);
       
  1070 
       
  1071             iDbHandler->GetSongL(aPath.Id(levels - 1).iId2, aAttrs, *aArray);
       
  1072 
       
  1073             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAllL_Song);
       
  1074             break;
       
  1075             }
       
  1076 
       
  1077          default:
       
  1078             {
       
  1079             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseAllL: Invalid levels[%d]", levels);
       
  1080             User::Leave(KErrNotSupported);
       
  1081             }
       
  1082         } // end switch(levels)
       
  1083 
       
  1084     return (levels == 3);
       
  1085     }
       
  1086 
       
  1087 // ----------------------------------------------------------------------------
       
  1088 // Handles OpenL called for EBrowseArtist
       
  1089 // ----------------------------------------------------------------------------
       
  1090 //
       
  1091 TBool CMPXDbPlugin::DoOpenBrowseArtistL(
       
  1092     const CMPXCollectionPath& aPath,
       
  1093     const TArray<TMPXAttribute>& aAttrs,
       
  1094     CMPXMedia& aEntries,
       
  1095     CMPXMediaArray* aArray)
       
  1096     {
       
  1097     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseArtistL");
       
  1098 
       
  1099     TBool isASong(EFalse);
       
  1100     TInt levels(aPath.Levels());
       
  1101     TInt idIndex(levels - 1);
       
  1102 
       
  1103     RArray<TMPXItemId> selections;
       
  1104     CleanupClosePushL(selections);
       
  1105     aPath.SelectionL(selections);
       
  1106 
       
  1107     switch (levels)
       
  1108         {
       
  1109         // All artists
       
  1110         case 2:
       
  1111             {
       
  1112             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_All);
       
  1113 
       
  1114             iDbHandler->GetAllArtistsL(aAttrs, aArray);
       
  1115             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXArtist,
       
  1116                 iMusicLibraryTitles->MdcaPoint(EBrowseArtist));
       
  1117 
       
  1118             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_All);
       
  1119             break;
       
  1120             }
       
  1121 
       
  1122         // All albums of an artist
       
  1123         case 3:
       
  1124             {
       
  1125             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_AllAlbums);
       
  1126             // get the albums
       
  1127             TInt id(aPath.Id(idIndex).iId2);
       
  1128             MPX_ASSERT(aArray->Count());
       
  1129             MPX_ASSERT((*aArray)[0]->IsSupported(KMPXMediaGeneralValue));
       
  1130             TInt pPath = (*aArray)[0]->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
  1131             MPX_ASSERT(pPath);
       
  1132             iDbHandler->GetAlbumsMatchingArtistL(id, aAttrs, *aArray);
       
  1133             SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXArtist, id);
       
  1134 
       
  1135             TInt count = aArray->Count();
       
  1136             if ( count > 2 )
       
  1137                 {
       
  1138                 // Only show "all" item if there is more than 1 album
       
  1139                 // count for "all" item
       
  1140                 TInt total = 0;
       
  1141                 for ( TInt i = 1; i < count; i++ )
       
  1142                 {
       
  1143                 TInt temp = (*aArray)[i]->ValueTObjectL<TInt>(KMPXMediaGeneralCount);
       
  1144                 total += temp;
       
  1145                 }
       
  1146             // Add "all" item under an artist
       
  1147             MPXDbCommonUtil::PrependMediaL(*aArray, *iAllSongsForArtistTitle, EMPXItem, EMPXAlbum,
       
  1148                 aPath.Id(idIndex), 0, 0, 1);
       
  1149     
       
  1150                 (*aArray)[1]->SetTObjectValueL<TInt>(KMPXMediaGeneralCount, total);
       
  1151     
       
  1152             TMPXItemId allId = ((*aArray)[1]->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
       
  1153             if (aArray->Count() > 2)
       
  1154                 { // path media, all id  and at least one media
       
  1155                 ((CMPXCollectionPath*)pPath)->InsertL(allId, 0);
       
  1156                 }
       
  1157             else
       
  1158                 { // only has all item
       
  1159                 ((CMPXCollectionPath*)pPath)->AppendL(allId);
       
  1160                     }
       
  1161                 }
       
  1162 
       
  1163             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_AllAlbums);
       
  1164             break;
       
  1165             }
       
  1166 
       
  1167         // All songs of an album for an artist or all songs for an artist
       
  1168         case 4:
       
  1169             {
       
  1170             // all songs for an artist
       
  1171             if (aPath.Id(3) == aPath.Id(2))
       
  1172                 {
       
  1173                 MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_AllSongs);
       
  1174 
       
  1175                 TInt id(aPath.Id(idIndex - 1).iId2);
       
  1176                 iDbHandler->GetSongsMatchingArtistL(id, aAttrs, aArray);
       
  1177                 SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXSong, id);
       
  1178 
       
  1179                 MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_AllSongs);
       
  1180                 }
       
  1181             // all songs of an album for an artist
       
  1182             else
       
  1183                 {
       
  1184                 MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_AllSongsForAlbum);
       
  1185                 TUint32 artistId(aPath.Id(idIndex - 1).iId2);
       
  1186 
       
  1187                 if (selections.Count())
       
  1188                     {
       
  1189                     // Multiple albums
       
  1190                     const TInt count(aPath.Selection().Count());
       
  1191                     for (TInt i = 0; i < count; ++i)
       
  1192                         {
       
  1193                         iDbHandler->GetSongsMatchingArtistAndAlbumL(artistId, selections[i].iId2,
       
  1194                             aAttrs, aArray);
       
  1195                         }
       
  1196                     }
       
  1197                 else
       
  1198                     {
       
  1199                     // One album
       
  1200                     iDbHandler->GetSongsMatchingArtistAndAlbumL(artistId, aPath.Id(idIndex).iId2,
       
  1201                         aAttrs, aArray);
       
  1202                     }
       
  1203 
       
  1204                 SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXAlbum, aPath.Id(idIndex).iId2);
       
  1205                 MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_AllSongsForAlbum);
       
  1206                 }
       
  1207 
       
  1208             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseArtistL: retrieved %d items", aArray->Count());
       
  1209 
       
  1210             break;
       
  1211             }
       
  1212 
       
  1213         // A Song in an album
       
  1214         case 5:
       
  1215             {
       
  1216             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseArtistL_Song);
       
  1217 
       
  1218             iDbHandler->GetSongL(aPath.Id(idIndex).iId2, aAttrs, *aArray);
       
  1219             isASong = ETrue;
       
  1220 
       
  1221             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseArtistL_Song);
       
  1222             break;
       
  1223             }
       
  1224 
       
  1225         default:
       
  1226             {
       
  1227             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseArtistL: Invalid levels[%d]", levels);
       
  1228             User::Leave(KErrNotSupported);
       
  1229             }
       
  1230         } // end switch(level)
       
  1231 
       
  1232     CleanupStack::PopAndDestroy(&selections);
       
  1233     return isASong;
       
  1234     }
       
  1235 
       
  1236 // ----------------------------------------------------------------------------
       
  1237 // Handles OpenL called for EBrowseAlbum
       
  1238 // ----------------------------------------------------------------------------
       
  1239 //
       
  1240 TBool CMPXDbPlugin::DoOpenBrowseAlbumL(
       
  1241     const CMPXCollectionPath& aPath,
       
  1242     const TArray<TMPXAttribute>& aAttrs,
       
  1243     CMPXMedia& aEntries,
       
  1244     CMPXMediaArray* aArray)
       
  1245     {
       
  1246     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseAlbumL");
       
  1247 
       
  1248     TBool isASong(EFalse);
       
  1249     TInt levels(aPath.Levels());
       
  1250     TInt idIndex(levels - 1);
       
  1251 
       
  1252     RArray<TMPXItemId> selections;
       
  1253     CleanupClosePushL(selections);
       
  1254     aPath.SelectionL(selections);
       
  1255 
       
  1256     switch (levels)
       
  1257         {
       
  1258         // All Albums
       
  1259         case 2:
       
  1260             {
       
  1261             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAlbumL_All);
       
  1262 
       
  1263             TRAPD(err, iDbHandler->GetAllAlbumsL(aAttrs, aArray) );
       
  1264             // in error case, return empty list and append empty id to path 
       
  1265             // in order to increase one level 
       
  1266             if ( err != KErrNone )
       
  1267                 {
       
  1268                 TInt pPath(0);
       
  1269                 if (aArray->Count())
       
  1270                     {
       
  1271                     CMPXMedia* pMedia = (*aArray)[0];
       
  1272                     if (pMedia->IsSupported(KMPXMediaGeneralValue))
       
  1273                         {
       
  1274                         pPath = pMedia->ValueTObjectL<TInt>(KMPXMediaGeneralValue);
       
  1275                         MPX_ASSERT(pPath);
       
  1276                         }                   
       
  1277                     }
       
  1278 
       
  1279                 RArray<TMPXItemId> ids;
       
  1280                 CleanupClosePushL(ids);
       
  1281             
       
  1282                 // Append ids to the returned path
       
  1283                 if (pPath)
       
  1284                     {
       
  1285                     ((CMPXCollectionPath*)pPath)->AppendL(ids.Array());
       
  1286                     }
       
  1287                 CleanupStack::PopAndDestroy(&ids);
       
  1288                 }
       
  1289             
       
  1290             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXAlbum,
       
  1291                 iMusicLibraryTitles->MdcaPoint(EBrowseAlbum));
       
  1292 
       
  1293             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAlbumL_All);
       
  1294             break;
       
  1295             }
       
  1296 
       
  1297         // All songs in one or multiple albums
       
  1298         case 3:
       
  1299             {
       
  1300             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAlbumL_AllSongs);
       
  1301             if (selections.Count())
       
  1302                 {
       
  1303                 // Multiple albums
       
  1304                 const TInt count(aPath.Selection().Count());
       
  1305                 for (TInt i = 0; i < count; ++i)
       
  1306                     {
       
  1307                     iDbHandler->GetSongsMatchingAlbumL(selections[i].iId2, aAttrs, aArray);
       
  1308                     }
       
  1309                 }
       
  1310             else
       
  1311                 {
       
  1312                 // One album
       
  1313                 iDbHandler->GetSongsMatchingAlbumL(aPath.Id(idIndex).iId2, aAttrs, aArray);
       
  1314                 }
       
  1315 
       
  1316 				// added for ganes
       
  1317                 SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXAlbum, iMusicLibraryTitles->MdcaPoint(EBrowseAlbumSong));
       
  1318 
       
  1319             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAlbumL_AllSongs);
       
  1320             break;
       
  1321             }
       
  1322 
       
  1323         // A song in an album
       
  1324         case 4:
       
  1325             {
       
  1326             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseAlbumL_Song);
       
  1327 
       
  1328             iDbHandler->GetSongL(aPath.Id(idIndex).iId2, aAttrs, *aArray);
       
  1329             isASong = ETrue;
       
  1330 
       
  1331             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseAlbumL_Song);
       
  1332             break;
       
  1333             }
       
  1334 
       
  1335         default:
       
  1336             {
       
  1337             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseAlbumL: Invalid levels[%d]", levels);
       
  1338             User::Leave(KErrNotSupported);
       
  1339             }
       
  1340         }
       
  1341 
       
  1342     CleanupStack::PopAndDestroy(&selections);
       
  1343     return isASong;
       
  1344     }
       
  1345 
       
  1346 // ----------------------------------------------------------------------------
       
  1347 // Handles OpenL called for EBrowsePlaylist
       
  1348 // ----------------------------------------------------------------------------
       
  1349 //
       
  1350 TBool CMPXDbPlugin::DoOpenBrowsePlaylistL(
       
  1351     const CMPXCollectionPath& aPath,
       
  1352     const TArray<TMPXAttribute>& aAttrs,
       
  1353     CMPXMedia& aEntries,
       
  1354     CMPXMediaArray* aArray)
       
  1355     {
       
  1356     MPX_FUNC("CMPXDbPlugin::DoOpenBrowsePlaylistL");
       
  1357 
       
  1358     TBool isASong(EFalse);
       
  1359     TInt levels(aPath.Levels());
       
  1360     TInt idIndex(levels - 1);
       
  1361 
       
  1362     RArray<TMPXItemId> selections;
       
  1363     CleanupClosePushL(selections);
       
  1364     aPath.SelectionL(selections);
       
  1365 
       
  1366     switch (levels)
       
  1367          {
       
  1368          case 2:
       
  1369             {
       
  1370             // All playlists
       
  1371             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowsePlaylistL_All);
       
  1372 
       
  1373             iDbHandler->GetAllPlaylistsL(aArray, aAttrs);
       
  1374             iDbHandler->GetAllSystemPlaylistNamesL(aArray);
       
  1375 
       
  1376             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXPlaylist,
       
  1377                 iMusicLibraryTitles->MdcaPoint(EBrowsePlaylist));
       
  1378 
       
  1379             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowsePlaylistL_All);
       
  1380             break;
       
  1381             }
       
  1382 
       
  1383          // All songs in a playlist
       
  1384          case 3:
       
  1385             {
       
  1386             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowsePlaylistL_AllSongs);
       
  1387 
       
  1388             if (selections.Count())
       
  1389                 {
       
  1390                 const TInt count(aPath.Selection().Count());
       
  1391                 for (TInt i = 0; i < count; ++i)
       
  1392                     {
       
  1393                     iDbHandler->GetSongsMatchingPlaylistL(selections[i].iId2, aAttrs, aArray);
       
  1394                     }
       
  1395                 }
       
  1396             else
       
  1397                 {
       
  1398                 iDbHandler->GetSongsMatchingPlaylistL(aPath.Id (idIndex).iId2, aAttrs, aArray);
       
  1399                 }
       
  1400 
       
  1401             SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXPlaylist, aPath.Id(idIndex).iId2);
       
  1402 
       
  1403             // populate EMPXMediaGeneralNonPermissibleActions
       
  1404             if (iDbHandler->IsAutoPlaylistL(aPath.Id(idIndex).iId2))
       
  1405                 {
       
  1406                 // set non-permissible actions to not writable and cacheable
       
  1407                 aEntries.SetTObjectValueL<TMPXGeneralNonPermissibleActions>(
       
  1408                     KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions)(EMPXWrite | EMPXCache));
       
  1409                 }
       
  1410 
       
  1411             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowsePlaylistL_AllSongs);
       
  1412             break;
       
  1413             }
       
  1414 
       
  1415          // Specific song in a playlist
       
  1416          case 4:
       
  1417             {
       
  1418             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowsePlaylistL_Song);
       
  1419 
       
  1420             iDbHandler->GetPlaylistSongL(aPath.Id(idIndex).iId2, aPath.Id(idIndex - 1).iId2,
       
  1421                 aAttrs, *aArray);
       
  1422             isASong = ETrue;
       
  1423 
       
  1424             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowsePlaylistL_Song);
       
  1425             break;
       
  1426             }
       
  1427 
       
  1428          default:
       
  1429             {
       
  1430             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowsePlaylistL: Invalid levels[%d]", levels);
       
  1431             User::Leave(KErrNotSupported);
       
  1432             }
       
  1433        }
       
  1434 
       
  1435     CleanupStack::PopAndDestroy(&selections);
       
  1436     return isASong;
       
  1437     }
       
  1438 
       
  1439 // ----------------------------------------------------------------------------
       
  1440 // Handles OpenL called for EBrowseGenre
       
  1441 // ----------------------------------------------------------------------------
       
  1442 //
       
  1443 TBool CMPXDbPlugin::DoOpenBrowseGenreL(
       
  1444     const CMPXCollectionPath& aPath,
       
  1445     const TArray<TMPXAttribute>& aAttrs,
       
  1446     CMPXMedia& aEntries,
       
  1447     CMPXMediaArray* aArray)
       
  1448     {
       
  1449     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseGenreL");
       
  1450 
       
  1451     TBool isASong(EFalse);
       
  1452     TInt levels(aPath.Levels());
       
  1453     TInt idIndex(levels - 1);
       
  1454 
       
  1455     RArray<TMPXItemId> selections;
       
  1456     CleanupClosePushL(selections);
       
  1457     aPath.SelectionL(selections);
       
  1458 
       
  1459     switch (levels)
       
  1460         {
       
  1461         // All genres
       
  1462          case 2:
       
  1463             {
       
  1464             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseGenreL_All);
       
  1465 
       
  1466             iDbHandler->GetAllGenresL(aAttrs, aArray);
       
  1467             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXGenre,
       
  1468                 iMusicLibraryTitles->MdcaPoint(EBrowseGenre));
       
  1469 
       
  1470             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseGenreL_All);
       
  1471             break;
       
  1472             }
       
  1473 
       
  1474         // All songs of a genre
       
  1475         case 3:
       
  1476             {
       
  1477             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseGenreL_AllSongs);
       
  1478 
       
  1479             if (selections.Count())
       
  1480                 {
       
  1481                 const TInt count(aPath.Selection().Count());
       
  1482                 for (TInt i = 0; i < count; ++i)
       
  1483                     {
       
  1484                     iDbHandler->GetSongsMatchingGenreL(selections[i].iId2, aAttrs, aArray);
       
  1485                     }
       
  1486                 }
       
  1487             else
       
  1488                 {
       
  1489                 iDbHandler->GetSongsMatchingGenreL(aPath.Id(idIndex).iId2, aAttrs, aArray);
       
  1490                 }
       
  1491             SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXGenre, aPath.Id(idIndex).iId2);
       
  1492 
       
  1493             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseGenreL_AllSongs);
       
  1494             break;
       
  1495             }
       
  1496 
       
  1497         // Specific song in a genre
       
  1498         case 4:
       
  1499             {
       
  1500             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseGenreL_Song);
       
  1501 
       
  1502             iDbHandler->GetSongL(aPath.Id(idIndex).iId2, aAttrs, *aArray);
       
  1503             isASong = ETrue;
       
  1504 
       
  1505             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseGenreL_Song);
       
  1506             break;
       
  1507             }
       
  1508 
       
  1509         default:
       
  1510             {
       
  1511             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseGenreL: Invalid levels[%d]", levels);
       
  1512             User::Leave(KErrNotSupported);
       
  1513             }
       
  1514         }
       
  1515 
       
  1516     CleanupStack::PopAndDestroy(&selections);
       
  1517     return isASong;
       
  1518     }
       
  1519 
       
  1520 // ----------------------------------------------------------------------------
       
  1521 // Handles OpenL called for EBrowseComposer
       
  1522 // ----------------------------------------------------------------------------
       
  1523 //
       
  1524 TBool CMPXDbPlugin::DoOpenBrowseComposerL(
       
  1525     const CMPXCollectionPath& aPath,
       
  1526     const TArray<TMPXAttribute>& aAttrs,
       
  1527     CMPXMedia& aEntries,
       
  1528     CMPXMediaArray* aArray)
       
  1529     {
       
  1530     MPX_FUNC("CMPXDbPlugin::DoOpenBrowseComposerL");
       
  1531 
       
  1532     TBool isASong(EFalse);
       
  1533     TInt levels(aPath.Levels());
       
  1534     TInt idIndex(levels - 1);
       
  1535 
       
  1536     RArray<TMPXItemId> selections;
       
  1537     CleanupClosePushL(selections);
       
  1538     aPath.SelectionL(selections);
       
  1539 
       
  1540     switch (levels)
       
  1541         {
       
  1542         // All composers
       
  1543         case 2:
       
  1544             {
       
  1545             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseComposerL_All);
       
  1546 
       
  1547             iDbHandler->GetAllComposersL(aAttrs, aArray);
       
  1548             SetMediaGeneralAttributesL(aEntries, EMPXGroup, EMPXComposer,
       
  1549                 iMusicLibraryTitles->MdcaPoint(EBrowseComposer));
       
  1550 
       
  1551             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseComposerL_All);
       
  1552             break;
       
  1553             }
       
  1554 
       
  1555         // All songs of a composer
       
  1556         case 3:
       
  1557             {
       
  1558             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseComposerL_AllSongs);
       
  1559             if (selections.Count())
       
  1560                 {
       
  1561                 const TInt count(aPath.Selection().Count());
       
  1562                 for (TInt i = 0; i < count; ++i)
       
  1563                     {
       
  1564                     iDbHandler->GetSongsMatchingComposerL(selections[i].iId2, aAttrs, aArray);
       
  1565                     }
       
  1566                 }
       
  1567             else
       
  1568                 {
       
  1569                 iDbHandler->GetSongsMatchingComposerL(aPath.Id(idIndex).iId2, aAttrs, aArray);
       
  1570                 }
       
  1571             SetMediaGeneralAttributesL(aEntries, EMPXItem, EMPXComposer, aPath.Id(idIndex).iId2);
       
  1572 
       
  1573             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseComposerL_AllSongs);
       
  1574             break;
       
  1575             }
       
  1576 
       
  1577         // Specific song of a composer
       
  1578         case 4:
       
  1579             {
       
  1580             MPX_PERF_START(CMPXDbPlugin_DoOpenBrowseComposerL_Song);
       
  1581 
       
  1582             iDbHandler->GetSongL(aPath.Id(idIndex).iId2, aAttrs, *aArray);
       
  1583             isASong = ETrue;
       
  1584 
       
  1585             MPX_PERF_END(CMPXDbPlugin_DoOpenBrowseComposerL_Song);
       
  1586             break;
       
  1587             }
       
  1588 
       
  1589         default:
       
  1590             {
       
  1591             MPX_DEBUG2("CMPXDbPlugin_DoOpenBrowseComposerL: Invalid levels[%d]", levels);
       
  1592             User::Leave(KErrNotSupported);
       
  1593             }
       
  1594         }
       
  1595 
       
  1596     CleanupStack::PopAndDestroy(&selections);
       
  1597     return isASong;
       
  1598     }
       
  1599 
       
  1600 // ----------------------------------------------------------------------------
       
  1601 // Process the OpenL method with open mode EMPXOpenPlaylistOnly
       
  1602 // ----------------------------------------------------------------------------
       
  1603 //
       
  1604 CMPXCollectionPath* CMPXDbPlugin::DoOpenPlaylistL(
       
  1605     const CMPXCollectionPath& aPath,
       
  1606     const TArray<TMPXAttribute>& aAttrs )
       
  1607     {
       
  1608     MPX_FUNC("CMPXDbPlugin::DoOpenPlaylistL");
       
  1609 
       
  1610     RArray<TMPXItemId> ids;
       
  1611     CleanupClosePushL(ids);
       
  1612 
       
  1613     CMPXMedia* entries = CMPXMedia::NewL();
       
  1614     CleanupStack::PushL(entries);
       
  1615 
       
  1616     CMPXCollectionPath* path = CMPXCollectionPath::NewL(aPath);
       
  1617     CleanupStack::PushL(path);
       
  1618 
       
  1619     // Go through the browse path
       
  1620     TInt levels(aPath.Levels());
       
  1621     if (levels == 2)
       
  1622         {
       
  1623         // Create a new collection path
       
  1624         CleanupStack::PopAndDestroy( path );
       
  1625         path = CMPXCollectionPath::NewL();
       
  1626         CleanupStack::PushL( path );
       
  1627 
       
  1628         // Always return all songs here
       
  1629         ids.Reset();
       
  1630         ids.AppendL( KDBPluginUid );
       
  1631         path->AppendL(ids.Array());
       
  1632         path->SelectL((TMPXItemId) KDBPluginUid);
       
  1633 
       
  1634         ids.Reset();
       
  1635         ids.AppendL(EBrowseAll);
       
  1636         path->AppendL(ids.Array());
       
  1637         path->SelectL((TMPXItemId) EBrowseAll);
       
  1638         path->Set(EMPXOpenPlaylistOnly);
       
  1639 
       
  1640         // Get all item IDs
       
  1641         CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  1642         CleanupStack::PushL(array);
       
  1643 
       
  1644         DoOpenBrowseAllL(*path, aAttrs, *entries, array);
       
  1645 
       
  1646         entries->SetCObjectValueL(KMPXMediaArrayContents, array);
       
  1647         entries->SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  1648 
       
  1649         CleanupStack::PopAndDestroy(array);
       
  1650 
       
  1651         DoAppendLevelL(*path, *entries);
       
  1652         }
       
  1653     else if (levels > 2)
       
  1654         {
       
  1655         switch (aPath.Id(1).iId2)
       
  1656             {
       
  1657             case EBrowseAll:
       
  1658                 {
       
  1659                 path->Set(EMPXOpenPlaylistOnly);
       
  1660                 // Returns the same path that we copied
       
  1661                 break;
       
  1662                 }
       
  1663             case EBrowseArtist:
       
  1664                 {
       
  1665                 if (levels == 3)
       
  1666                     {
       
  1667                     // return all songs of a particular artist (currently highlighted)
       
  1668                     path->Set(EMPXOpenGroupOrPlaylist);
       
  1669                     ids.Reset();
       
  1670                     ids.Append(aPath.Id(2));
       
  1671                     path->AppendL(ids.Array());
       
  1672                     path->SelectL(aPath.Id(2));
       
  1673                     path->Set(EMPXOpenPlaylistOnly);
       
  1674 
       
  1675                     // Opens all songs of an artist and create the corresponding
       
  1676                     // Collection playlist by appending all songs of an artist to
       
  1677                     // the collection path
       
  1678                     //
       
  1679                     DoOpenL(*path, aAttrs, *entries, NULL);
       
  1680                     DoAppendLevelL(*path, *entries);
       
  1681                     }
       
  1682                 else if (levels == 4)
       
  1683                     {
       
  1684                     // Open the album of an artist and create the corresponding
       
  1685                     // Collection playlist by appending all songs of an artist to
       
  1686                     // the collection path
       
  1687                     //
       
  1688                     path->Set(EMPXOpenPlaylistOnly);
       
  1689                     DoOpenL(*path, aAttrs, *entries, NULL);
       
  1690                     DoAppendLevelL(*path, *entries);
       
  1691                     }
       
  1692                 else
       
  1693                     {
       
  1694                     // case is a song no need to open again!
       
  1695                     }
       
  1696 
       
  1697                 break;
       
  1698                 }
       
  1699             // Playlist, album, genre and composer easier, only 2 levels deep
       
  1700             // plugin | category | category contents | songs of category
       
  1701             //
       
  1702             case EBrowsePlaylist:
       
  1703             case EBrowseAlbum:
       
  1704             case EBrowseGenre:
       
  1705             case EBrowseComposer:
       
  1706                 {
       
  1707                 if (!DoOpenL(aPath, aAttrs, *entries, NULL))
       
  1708                     {
       
  1709                     // If it is not at a song level
       
  1710                     // Append all entries to create collection path
       
  1711                     //
       
  1712                     path->Set(EMPXOpenPlaylistOnly);
       
  1713                     DoAppendLevelL( *path, *entries );
       
  1714                     }
       
  1715                 break;
       
  1716                 }
       
  1717             default:
       
  1718                 {
       
  1719                 User::Leave(KErrNotSupported);
       
  1720                 }
       
  1721             }
       
  1722         }
       
  1723     else  // levels < 2
       
  1724         {
       
  1725         User::Leave(KErrNotSupported);
       
  1726         }
       
  1727 
       
  1728     // Cleanup
       
  1729     CleanupStack::Pop(path);
       
  1730     CleanupStack::PopAndDestroy(entries);
       
  1731     CleanupStack::PopAndDestroy(&ids);
       
  1732 
       
  1733     return path;
       
  1734     }
       
  1735 
       
  1736 // ----------------------------------------------------------------------------
       
  1737 // Process the MediaL command
       
  1738 // ----------------------------------------------------------------------------
       
  1739 //
       
  1740 void CMPXDbPlugin::DoMediaL(
       
  1741     const CMPXCollectionPath& aPath,
       
  1742     const TArray<TMPXAttribute>& aAttrs,
       
  1743     CMPXMedia& aEntries)
       
  1744     {
       
  1745     MPX_FUNC("CMPXDbPlugin::DoMediaL");
       
  1746 
       
  1747     // Fetch Media for root level
       
  1748     //
       
  1749     if (aPath.Levels() == 1) //root
       
  1750         {
       
  1751         DoRootMediaL( aAttrs, aEntries );
       
  1752         }
       
  1753     // Ensure the database has been merged before attempting MediaL()
       
  1754     //
       
  1755     else
       
  1756         {
       
  1757         CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  1758         CleanupStack::PushL(array);
       
  1759 
       
  1760         switch (aPath.Id(1).iId2)
       
  1761             {
       
  1762             case EBrowseAll:
       
  1763                 {
       
  1764                 DoAllSongsMediaL(aPath, aAttrs, aEntries, *array);
       
  1765                 break;
       
  1766                 } // end case EBrowseAll
       
  1767 
       
  1768             case EBrowseArtist:
       
  1769                 {
       
  1770                 DoArtistMediaL(aPath, aAttrs, aEntries, *array);
       
  1771                 break;
       
  1772                 } // end case EBrowseArtist
       
  1773 
       
  1774             case EBrowseAlbum:
       
  1775                 {
       
  1776                 DoCategoryMediaL(aPath, aAttrs, EMPXAlbum, aEntries, *array);
       
  1777                 break;
       
  1778                 } // end case EBrowseAlbum
       
  1779 
       
  1780             case EBrowsePlaylist:
       
  1781                 {
       
  1782                 DoCategoryMediaL(aPath, aAttrs, EMPXPlaylist, aEntries, *array);
       
  1783                 break;
       
  1784                 } // end case EBrowsePlaylist
       
  1785 
       
  1786             case EBrowseGenre:
       
  1787                 {
       
  1788                 DoCategoryMediaL(aPath, aAttrs, EMPXGenre, aEntries, *array);
       
  1789                 break;
       
  1790                 } // end case EBrowseGenre
       
  1791 
       
  1792             case EBrowseComposer:
       
  1793                 {
       
  1794                 DoCategoryMediaL(aPath, aAttrs, EMPXComposer, aEntries, *array);
       
  1795                 break;
       
  1796                 } // end case EBrowseComposer
       
  1797 #ifdef __ENABLE_PODCAST_IN_MUSIC_MENU
       
  1798             case EBrowsePodcasts:
       
  1799                 {
       
  1800                 break;
       
  1801                 }
       
  1802 #endif
       
  1803             default:
       
  1804                 {
       
  1805                 User::Leave(KErrArgument);
       
  1806                 }
       
  1807             } // end switch(aPath.id(1)
       
  1808 
       
  1809         if (array->Count() > 0)
       
  1810             {
       
  1811             aEntries.SetCObjectValueL(KMPXMediaArrayContents, array);
       
  1812             aEntries.SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  1813             }
       
  1814         CleanupStack::PopAndDestroy(array);
       
  1815         }
       
  1816     // Else case cannot leave, because this will happen when we have no disk space to
       
  1817     // perform the merging. It should NOT leave.
       
  1818     //
       
  1819     }
       
  1820 
       
  1821 // ----------------------------------------------------------------------------
       
  1822 // Find the collection media for root level
       
  1823 // ----------------------------------------------------------------------------
       
  1824 //
       
  1825 void CMPXDbPlugin::DoRootMediaL(
       
  1826     const TArray<TMPXAttribute>& aAttrs,
       
  1827     CMPXMedia& aMedia )
       
  1828     {
       
  1829     MPX_FUNC("CMPXDbPlugin::DoRootMediaL");
       
  1830 
       
  1831     TInt count(aAttrs.Count());
       
  1832 #ifndef __ENABLE_PODCAST_IN_MUSIC_MENU
       
  1833     aMedia.SetTObjectValueL<TMPXGeneralNonPermissibleActions> (
       
  1834             KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions)(EMPXWrite | EMPXCache) );
       
  1835 #endif // __ENABLE_PODCAST_IN_MUSIC_MENU
       
  1836     for (TInt i = 0; i < count; ++i)
       
  1837         {
       
  1838         if (aAttrs[i].ContentId() == KMPXMediaIdGeneral)
       
  1839             {
       
  1840             TUint att(aAttrs[i].AttributeId());
       
  1841             if (att & EMPXMediaGeneralTitle)
       
  1842                 {
       
  1843                 HBufC* title(iResource->ReadHBufCL(R_MPX_QTN_MUS_MUSIC));
       
  1844                 CleanupStack::PushL(title);
       
  1845                 aMedia.SetTextValueL(KMPXMediaGeneralTitle, *title);
       
  1846                 CleanupStack::PopAndDestroy(title);
       
  1847                 }
       
  1848             if (att & EMPXMediaGeneralSubTitle)
       
  1849                 {
       
  1850                 TInt numSongs(iDbHandler->NumberOfItemsL(EMPXSong));
       
  1851                 aMedia.SetTObjectValueL<TInt>(KMPXMediaGeneralCount, numSongs);
       
  1852 
       
  1853                 HBufC* text(iResource->ReadHBufCL((1 == numSongs) ?
       
  1854                     R_MPX_QTN_MUS_MUSIC_ONE_SONG : R_MPX_QTN_MUS_MUSIC_NUM_SONGS));
       
  1855 
       
  1856                 CleanupStack::PushL(text);
       
  1857                 aMedia.SetTextValueL(KMPXMediaGeneralSubTitle, *text);
       
  1858                 CleanupStack::PopAndDestroy(text);
       
  1859                 }
       
  1860             if (att & EMPXMediaGeneralIcon)
       
  1861                 {
       
  1862 /*                TIconInfo icon;
       
  1863                 icon.bmpfile = KMPlayerDbPluginMbmFile;
       
  1864                 icon.bitmapId = EMbmMpxdbpluginQgn_graf_mup_dlst_music;
       
  1865                 icon.maskId = EMbmMpxdbpluginQgn_graf_mup_dlst_music_mask;
       
  1866                 aMedia.SetTObjectValueL<TIconInfo>(KMPXMediaGeneralIcon, icon);
       
  1867 */
       
  1868 // commented out for hb migration
       
  1869                 }
       
  1870             } // if
       
  1871         } // for
       
  1872     }
       
  1873 
       
  1874 // ----------------------------------------------------------------------------
       
  1875 // Find the collection media for all songs category
       
  1876 // ----------------------------------------------------------------------------
       
  1877 //
       
  1878 void CMPXDbPlugin::DoAllSongsMediaL(
       
  1879     const CMPXCollectionPath& aPath,
       
  1880     const TArray<TMPXAttribute>& aAttrs,
       
  1881     CMPXMedia& aEntries,
       
  1882     CMPXMediaArray& aMediaArray)
       
  1883     {
       
  1884     MPX_FUNC("CMPXDbPlugin::DoAllSongsMediaL");
       
  1885 
       
  1886     TInt levels(aPath.Levels());
       
  1887 
       
  1888     switch (levels)
       
  1889        {
       
  1890        // All songs
       
  1891        case 2:
       
  1892             {
       
  1893             MPX_PERF_START(CMPXDbPlugin_DoAllSongsMediaL_All);
       
  1894             DoRootCategoryMediaL(aAttrs, EBrowseAll, EMPXSong, aEntries);
       
  1895             MPX_PERF_END(CMPXDbPlugin_DoAllSongsMediaL_All);
       
  1896             break;
       
  1897             }
       
  1898 
       
  1899          // A Song in all songs
       
  1900          case 3:
       
  1901             {
       
  1902             MPX_PERF_START(CMPXDbPlugin_DoAllSongsMediaL_Song);
       
  1903             GetSongInfoL(aPath, aAttrs, aEntries, aMediaArray);
       
  1904             MPX_PERF_END(CMPXDbPlugin_DoAllSongsMediaL_Song);
       
  1905             break;
       
  1906             }
       
  1907 
       
  1908          default:
       
  1909             {
       
  1910             MPX_DEBUG2("CMPXDbPlugin_DoAllSongsMediaL: Invalid levels[%d]", levels);
       
  1911             User::Leave(KErrNotSupported);
       
  1912             }
       
  1913         } // end switch(levels)
       
  1914     }
       
  1915 
       
  1916 // ----------------------------------------------------------------------------
       
  1917 // Find the collection media for artists category
       
  1918 // ----------------------------------------------------------------------------
       
  1919 //
       
  1920 void CMPXDbPlugin::DoArtistMediaL (
       
  1921     const CMPXCollectionPath& aPath,
       
  1922     const TArray<TMPXAttribute>& aAttrs,
       
  1923     CMPXMedia& aEntries,
       
  1924     CMPXMediaArray& aMediaArray)
       
  1925     {
       
  1926     MPX_FUNC("CMPXDbPlugin::DoArtistMediaL");
       
  1927 
       
  1928     TInt levels(aPath.Levels());
       
  1929     TInt count(aPath.Selection().Count());
       
  1930 
       
  1931      // All artists
       
  1932     if (levels == 2)
       
  1933         {
       
  1934         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_All);
       
  1935         DoRootCategoryMediaL(aAttrs, EBrowseArtist, EMPXArtist, aEntries);
       
  1936         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_All);
       
  1937         }
       
  1938     else if ((levels == 3) && count) // multiple artists selected
       
  1939         {
       
  1940         RArray<TMPXItemId> selections;
       
  1941         CleanupClosePushL(selections);
       
  1942         aPath.SelectionL(selections);
       
  1943 
       
  1944         for (TInt i = 0; i < count; ++i)
       
  1945             {
       
  1946             CMPXMedia* artist = CMPXMedia::NewL();
       
  1947             CleanupStack::PushL(artist);
       
  1948             iDbHandler->GetCategoryL(selections[i].iId2, EMPXArtist, aAttrs, artist);
       
  1949             aMediaArray.AppendL(*artist);
       
  1950             CleanupStack::PopAndDestroy(artist);
       
  1951             }
       
  1952 
       
  1953         CleanupStack::PopAndDestroy(&selections);
       
  1954         }
       
  1955     else if (levels == 3) // single artist selected
       
  1956         {
       
  1957         iDbHandler->GetCategoryL(aPath.Id(2).iId2, EMPXArtist, aAttrs, &aEntries);
       
  1958         }
       
  1959     else if (levels == 4 && (aPath.Id(3) == aPath.Id(2))) // all songs for an artist
       
  1960         {
       
  1961         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_AllSongs);
       
  1962         // Calculate duration directly with SQL
       
  1963         if (MPXDbCommonUtil::AttributeExists(aAttrs, KMPXMediaGeneralDuration))
       
  1964             {
       
  1965             DoDurationL(aEntries, EMPXArtist, aPath.Id(2));
       
  1966             }
       
  1967 
       
  1968         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_AllSongs);
       
  1969         }
       
  1970     else if ((levels == 4) && count) // multiple albums of an artist
       
  1971         {
       
  1972         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_AllAlbums);
       
  1973 
       
  1974         RArray<TMPXItemId> selections;
       
  1975         CleanupClosePushL(selections);
       
  1976         aPath.SelectionL(selections);
       
  1977 
       
  1978         for (TInt i = 0; i < count; ++i)
       
  1979             {
       
  1980             CMPXMedia* media = CMPXMedia::NewL();
       
  1981             CleanupStack::PushL(media);
       
  1982             iDbHandler->GetCategoryL(selections[i].iId2, EMPXAlbum, aAttrs, media);
       
  1983             aMediaArray.AppendL(*media);
       
  1984             CleanupStack::PopAndDestroy(media);
       
  1985             }
       
  1986 
       
  1987         CleanupStack::PopAndDestroy(&selections);
       
  1988 
       
  1989         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_AllAlbums);
       
  1990         }
       
  1991     else if (levels == 4) // one album of an artist
       
  1992         {
       
  1993         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_OneAlbum);
       
  1994         iDbHandler->GetCategoryL(aPath.Id(3).iId2, EMPXAlbum, aAttrs, &aEntries);
       
  1995 
       
  1996         // Calculate duration
       
  1997         if (MPXDbCommonUtil::AttributeExists(aAttrs, KMPXMediaGeneralDuration))
       
  1998             {
       
  1999             DoDurationL(aEntries, EMPXArtist, aPath.Id(2), EMPXAlbum, aPath.Id(3));
       
  2000             }
       
  2001 
       
  2002         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_OneAlbum);
       
  2003         }
       
  2004      else if (levels == 5) // a song/songs in an album
       
  2005         {
       
  2006         MPX_PERF_START(CMPXDbPlugin_DoArtistMediaL_Song);
       
  2007         GetSongInfoL(aPath, aAttrs, aEntries, aMediaArray);
       
  2008         MPX_PERF_END(CMPXDbPlugin_DoArtistMediaL_Song);
       
  2009         }
       
  2010     else
       
  2011         {
       
  2012         MPX_DEBUG2("CMPXDbPlugin_DoArtistMediaL: Invalid levels[%d]", levels);
       
  2013         User::Leave(KErrNotSupported);
       
  2014         }
       
  2015     }
       
  2016 
       
  2017 // ----------------------------------------------------------------------------
       
  2018 // Find the collection media for all songs category
       
  2019 // ----------------------------------------------------------------------------
       
  2020 //
       
  2021 void CMPXDbPlugin::DoRootCategoryMediaL (
       
  2022     const TArray<TMPXAttribute>& aAttrs,
       
  2023     TMPXItemId aRootCategoryId,
       
  2024     TMPXGeneralCategory aCategory,
       
  2025     CMPXMedia& aEntries)
       
  2026     {
       
  2027     MPX_FUNC("CMPXDbPlugin::DoRootCategoryMediaL");
       
  2028 
       
  2029     TInt count(aAttrs.Count());
       
  2030     for (TInt i = 0; i < count; ++i)
       
  2031         {
       
  2032         if (aAttrs[i].ContentId() == KMPXMediaIdGeneral)
       
  2033             {
       
  2034             TUint att(aAttrs[i].AttributeId());
       
  2035             switch (att)
       
  2036                 {
       
  2037                 case EMPXMediaGeneralId:
       
  2038                     {
       
  2039                     aEntries.SetTObjectValueL<TMPXItemId>(KMPXMediaGeneralId, aRootCategoryId);
       
  2040                     break;
       
  2041                     }
       
  2042                 case EMPXMediaGeneralTitle:
       
  2043                     {
       
  2044                     aEntries.SetTextValueL(KMPXMediaGeneralTitle,
       
  2045                         iMusicLibraryMenuTitles->MdcaPoint(BrowseTypeForCategory(aCategory)));
       
  2046                     break;
       
  2047                     }
       
  2048                 case EMPXMediaGeneralCount:
       
  2049                     {
       
  2050                     // count number of category
       
  2051                     aEntries.SetTObjectValueL<TInt>(KMPXMediaGeneralCount,
       
  2052                         iDbHandler->NumberOfItemsL(aCategory));
       
  2053                     break;
       
  2054                     }
       
  2055                 case EMPXMediaGeneralDuration:
       
  2056                     {
       
  2057                     if (aCategory == EMPXSong)
       
  2058                         {
       
  2059                         DoDurationL(aEntries, EMPXSong);
       
  2060                         }
       
  2061                     break;
       
  2062                     }
       
  2063                 default:
       
  2064                     // not supported
       
  2065                     break;
       
  2066                 } // end switch
       
  2067             } // end if
       
  2068         } // end for
       
  2069 
       
  2070     aEntries.SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, EMPXGroup);
       
  2071     aEntries.SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, aCategory);
       
  2072     }
       
  2073 
       
  2074 // ----------------------------------------------------------------------------
       
  2075 // Find the collection media for albums/playlists/genres/composers category
       
  2076 // ----------------------------------------------------------------------------
       
  2077 //
       
  2078 void CMPXDbPlugin::DoCategoryMediaL(
       
  2079     const CMPXCollectionPath& aPath,
       
  2080     const TArray<TMPXAttribute>& aAttrs,
       
  2081     TMPXGeneralCategory aCategory,
       
  2082     CMPXMedia& aEntries,
       
  2083     CMPXMediaArray& aMediaArray)
       
  2084     {
       
  2085     MPX_FUNC("CMPXDbPlugin::DoCategoryMediaL");
       
  2086 
       
  2087     TInt levels(aPath.Levels());
       
  2088     TInt count(aPath.Selection().Count());
       
  2089 
       
  2090     if (levels == 2) // all albums/playlists/genres/composers
       
  2091         {
       
  2092         MPX_PERF_START (CMPXDbPlugin_DoCategoryMediaL_All);
       
  2093         DoRootCategoryMediaL(aAttrs, aPath.Id(1).iId2, aCategory, aEntries);
       
  2094         MPX_PERF_END (CMPXDbPlugin_DoCategoryMediaL_All);
       
  2095         }
       
  2096     else if (levels == 3 && count) // multiple albums/playlists/genres/composers selected
       
  2097         {
       
  2098         RArray<TMPXItemId> selections;
       
  2099         CleanupClosePushL(selections);
       
  2100         aPath.SelectionL(selections);
       
  2101 
       
  2102         for (TInt i = 0; i < count; ++i)
       
  2103             {
       
  2104             CMPXMedia* media = CMPXMedia::NewL();
       
  2105             CleanupStack::PushL(media);
       
  2106             iDbHandler->GetCategoryL(selections[i].iId2, aCategory, aAttrs, media);
       
  2107             aMediaArray.AppendL(*media);
       
  2108             CleanupStack::PopAndDestroy(media);
       
  2109             }
       
  2110 
       
  2111         CleanupStack::PopAndDestroy(&selections);
       
  2112         }
       
  2113     else if (levels == 3) // all songs in an album/playlist/genre/composer
       
  2114         {
       
  2115         MPX_PERF_START(CMPXDbPlugin_DoCategoryMediaL_Category);
       
  2116         TMPXItemId id = aPath.Id(2);
       
  2117         iDbHandler->GetCategoryL(id.iId2, aCategory, aAttrs, &aEntries);
       
  2118 
       
  2119         // Calculate duration directly with SQL
       
  2120         if (MPXDbCommonUtil::AttributeExists(aAttrs, KMPXMediaGeneralDuration))
       
  2121             {
       
  2122             DoDurationL(aEntries, aCategory, id);
       
  2123             }
       
  2124 
       
  2125         TInt nonPermisAction( aEntries.ValueTObjectL<TInt>(KMPXMediaGeneralNonPermissibleActions));
       
  2126         nonPermisAction |= EMPXCache;
       
  2127 
       
  2128         aEntries.SetTObjectValueL<TMPXGeneralNonPermissibleActions>(
       
  2129                     KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions) nonPermisAction );
       
  2130 
       
  2131         MPX_PERF_END(CMPXDbPlugin_DoCategoryMediaL_Category);
       
  2132         }
       
  2133     else if (levels == 4) // a song/songs in an album/playlist/genre/composer
       
  2134         {
       
  2135         MPX_PERF_START(CMPXDbPlugin_DoCategoryMediaL_Song);
       
  2136         GetSongInfoL(aPath, aAttrs, aEntries, aMediaArray);
       
  2137         MPX_PERF_END(CMPXDbPlugin_DoCategoryMediaL_Song);
       
  2138         }
       
  2139     else
       
  2140         {
       
  2141         MPX_DEBUG2("CMPXDbPlugin__DoMediaL__EBrowseAlbum: Invalid levels[%d]", levels);
       
  2142         User::Leave(KErrNotSupported);
       
  2143         }
       
  2144     }
       
  2145 
       
  2146 // ----------------------------------------------------------------------------
       
  2147 // Set all the attributes in CMPXMedia corresponding to KMPXMediaIdDrm
       
  2148 // ----------------------------------------------------------------------------
       
  2149 //
       
  2150 void CMPXDbPlugin::DoSetMediaDrmL(
       
  2151     CMPXMedia& aMedia,
       
  2152     TUint aDrmAttributes,
       
  2153     const TDesC& aLocation)
       
  2154     {
       
  2155     MPX_FUNC("CMPXDbPlugin::DoSetMediaDrmL");
       
  2156 
       
  2157     iDrmMediaUtility->InitL(aLocation);
       
  2158     CleanupClosePushL(*iDrmMediaUtility);
       
  2159     const CMPXMedia* drmMedia(iDrmMediaUtility->GetMediaL(aDrmAttributes));
       
  2160 
       
  2161     // Only get attributes if it's a DRM file
       
  2162     if (drmMedia)
       
  2163         {
       
  2164         if ((aDrmAttributes & EMPXMediaDrmType) &&
       
  2165             drmMedia->IsSupported(KMPXMediaDrmType))
       
  2166             {
       
  2167             aMedia.SetTObjectValueL(KMPXMediaDrmType,
       
  2168                 drmMedia->ValueTObjectL<TInt>(KMPXMediaDrmType));
       
  2169             }
       
  2170         if ((aDrmAttributes & EMPXMediaDrmRightsStatus) &&
       
  2171             drmMedia->IsSupported(KMPXMediaDrmRightsStatus))
       
  2172             {
       
  2173             aMedia.SetTObjectValueL(KMPXMediaDrmRightsStatus,
       
  2174                 drmMedia->ValueTObjectL<TInt>(KMPXMediaDrmRightsStatus));
       
  2175             }
       
  2176         if ((aDrmAttributes & EMPXMediaDrmRightsType) &&
       
  2177             drmMedia->IsSupported(KMPXMediaDrmRightsType))
       
  2178             {
       
  2179             aMedia.SetTObjectValueL(KMPXMediaDrmRightsType,
       
  2180                 drmMedia->ValueTObjectL<TInt>(KMPXMediaDrmRightsType));
       
  2181             }
       
  2182         if ((aDrmAttributes & EMPXMediaDrmCount) &&
       
  2183             drmMedia->IsSupported(KMPXMediaDrmCount))
       
  2184             {
       
  2185             aMedia.SetTObjectValueL(KMPXMediaDrmCount,
       
  2186                 drmMedia->ValueTObjectL<TInt>(KMPXMediaDrmCount));
       
  2187             }
       
  2188         if ((aDrmAttributes & EMPXMediaDrmProtected) &&
       
  2189             drmMedia->IsSupported(KMPXMediaDrmProtected))
       
  2190             {
       
  2191             aMedia.SetTObjectValueL(KMPXMediaDrmProtected,
       
  2192                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmProtected));
       
  2193             }
       
  2194         if ((aDrmAttributes & EMPXMediaDrmSendingAllowed) &&
       
  2195             drmMedia->IsSupported(KMPXMediaDrmSendingAllowed))
       
  2196             {
       
  2197             aMedia.SetTObjectValueL(KMPXMediaDrmSendingAllowed,
       
  2198                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmSendingAllowed));
       
  2199             }
       
  2200         if ((aDrmAttributes & EMPXMediaDrmCanSetAutomated) &&
       
  2201             drmMedia->IsSupported(KMPXMediaDrmCanSetAutomated))
       
  2202             {
       
  2203             aMedia.SetTObjectValueL(KMPXMediaDrmCanSetAutomated,
       
  2204                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmCanSetAutomated));
       
  2205             }
       
  2206         if ((aDrmAttributes & EMPXMediaDrmHasInfoUrl) &&
       
  2207             drmMedia->IsSupported(KMPXMediaDrmHasInfoUrl))
       
  2208             {
       
  2209             aMedia.SetTObjectValueL(KMPXMediaDrmHasInfoUrl,
       
  2210                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmHasInfoUrl));
       
  2211             }
       
  2212         if ((aDrmAttributes & EMPXMediaDrmHasPreviewUrl) &&
       
  2213             drmMedia->IsSupported(KMPXMediaDrmHasPreviewUrl))
       
  2214             {
       
  2215             aMedia.SetTObjectValueL(KMPXMediaDrmHasPreviewUrl,
       
  2216                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmHasPreviewUrl));
       
  2217             }
       
  2218         if ((aDrmAttributes & EMPXMediaDrmAboutToExpire) &&
       
  2219             drmMedia->IsSupported(KMPXMediaDrmAboutToExpire))
       
  2220             {
       
  2221             aMedia.SetTObjectValueL( KMPXMediaDrmAboutToExpire,
       
  2222                 drmMedia->ValueTObjectL<TBool>(KMPXMediaDrmAboutToExpire));
       
  2223             }
       
  2224         if ((aDrmAttributes & EMPXMediaDrmStartTime) &&
       
  2225             drmMedia->IsSupported(KMPXMediaDrmStartTime))
       
  2226             {
       
  2227             aMedia.SetTObjectValueL(KMPXMediaDrmStartTime,
       
  2228                 drmMedia->ValueTObjectL<TInt64>(KMPXMediaDrmStartTime));
       
  2229             }
       
  2230         if ((aDrmAttributes & EMPXMediaDrmEndTime) &&
       
  2231             drmMedia->IsSupported(KMPXMediaDrmEndTime))
       
  2232             {
       
  2233             aMedia.SetTObjectValueL( KMPXMediaDrmEndTime,
       
  2234                 drmMedia->ValueTObjectL<TInt64>(KMPXMediaDrmEndTime));
       
  2235             }
       
  2236         if ((aDrmAttributes & EMPXMediaDrmIntervalStartTime) &&
       
  2237             drmMedia->IsSupported(KMPXMediaDrmIntervalStartTime))
       
  2238             {
       
  2239             aMedia.SetTObjectValueL( KMPXMediaDrmIntervalStartTime,
       
  2240                 drmMedia->ValueTObjectL<TInt64>(KMPXMediaDrmIntervalStartTime));
       
  2241             }
       
  2242         if ((aDrmAttributes & EMPXMediaDrmAccumulatedTime) &&
       
  2243             drmMedia->IsSupported(KMPXMediaDrmAccumulatedTime))
       
  2244             {
       
  2245             aMedia.SetTObjectValueL(KMPXMediaDrmAccumulatedTime,
       
  2246                 drmMedia->ValueTObjectL<TInt64>(KMPXMediaDrmAccumulatedTime));
       
  2247             }
       
  2248         if ((aDrmAttributes & EMPXMediaDrmInterval) &&
       
  2249             drmMedia->IsSupported(KMPXMediaDrmInterval))
       
  2250             {
       
  2251             aMedia.SetTObjectValueL( KMPXMediaDrmInterval,
       
  2252                 drmMedia->ValueTObjectL<TTimeIntervalSeconds>(KMPXMediaDrmInterval));
       
  2253             }
       
  2254         }
       
  2255 
       
  2256     CleanupStack::PopAndDestroy(iDrmMediaUtility);
       
  2257     }
       
  2258 
       
  2259 // ----------------------------------------------------------------------------
       
  2260 // Add media objects to the array with attributes from song details
       
  2261 // ----------------------------------------------------------------------------
       
  2262 //
       
  2263 void CMPXDbPlugin::GetSongInfoL(
       
  2264     const CMPXCollectionPath& aPath,
       
  2265     const TArray<TMPXAttribute>& aAttrs,
       
  2266     CMPXMedia& aEntry,
       
  2267     CMPXMediaArray& aMediaArray)
       
  2268     {
       
  2269     MPX_FUNC("CMPXDbPlugin::GetSongInfoL");
       
  2270 
       
  2271     RArray<TInt> supportedIds;
       
  2272     CleanupClosePushL(supportedIds);
       
  2273     MPXDbCommonUtil::FillInSupportedUIDsL(aAttrs, supportedIds);
       
  2274 
       
  2275     RArray<TMPXItemId> selections;
       
  2276     CleanupClosePushL(selections);
       
  2277     aPath.SelectionL(selections);
       
  2278 
       
  2279     //
       
  2280     // If we are trying to locate a song from a playlist, we should read available song
       
  2281     // info from Playlist table first in case the song is located on a removable
       
  2282     // drive and the drive is not currently present. This is achieved by supplying
       
  2283     // playlist Id to GetSongMatchingSongIdL. When playlistId is 0, we are reading song
       
  2284     // info directly from Songs table. If playlistId is specified, GetSongMatchingSongIdL
       
  2285     // will populate song media from Playlist table and if Songs table for the drive
       
  2286     // exists, song media will be overwritten with info from Songs table.
       
  2287     //
       
  2288     TMPXItemId playlistId(0);
       
  2289     if (aPath.Id(1) == EBrowsePlaylist)
       
  2290         {
       
  2291         if (aPath.Levels() < 2)
       
  2292             {
       
  2293             User::Leave(KErrArgument);
       
  2294             }
       
  2295 
       
  2296         playlistId = aPath.Id(aPath.Levels() - 2);
       
  2297         }
       
  2298 
       
  2299     TInt countSelection(aPath.Selection().Count());
       
  2300     if (countSelection)
       
  2301         {
       
  2302         // We have a selection, iterate it
       
  2303         for (TInt selectionIndex = 0; selectionIndex < countSelection; ++selectionIndex)
       
  2304             {
       
  2305             CMPXMedia* newEntry = CMPXMedia::NewL(supportedIds.Array());
       
  2306             CleanupStack::PushL(newEntry);
       
  2307 
       
  2308             DoGetSongInfoL(aAttrs, selections[selectionIndex].iId2, playlistId.iId2, *newEntry);
       
  2309 
       
  2310             aMediaArray.AppendL(*newEntry);
       
  2311             CleanupStack::PopAndDestroy(newEntry);
       
  2312             }
       
  2313         }
       
  2314     else
       
  2315         {
       
  2316         // No selection, get the attributes for the one song
       
  2317         DoGetSongInfoL(aAttrs, aPath.Id(aPath.Levels() - 1).iId2, playlistId.iId2, aEntry);
       
  2318         }
       
  2319 
       
  2320     CleanupStack::PopAndDestroy(&selections);
       
  2321     CleanupStack::PopAndDestroy(&supportedIds);
       
  2322     }
       
  2323 
       
  2324 // ----------------------------------------------------------------------------
       
  2325 // Retrieves the attributes for a media object.
       
  2326 // ----------------------------------------------------------------------------
       
  2327 //
       
  2328 void CMPXDbPlugin::DoGetSongInfoL(
       
  2329     const TArray<TMPXAttribute>& aAttrs,
       
  2330     TInt aEntryId,
       
  2331     TInt aPlaylistId,
       
  2332     CMPXMedia& aEntry)
       
  2333     {
       
  2334     MPX_FUNC("CMPXDbPlugin::DoGetSongInfoL");
       
  2335 
       
  2336     if (aPlaylistId)
       
  2337         {
       
  2338         iDbHandler->GetPlaylistSongL(aEntryId, aPlaylistId, aAttrs, aEntry);
       
  2339         }
       
  2340     else
       
  2341         {
       
  2342         iDbHandler->GetSongL(aEntryId, aAttrs, aEntry);
       
  2343         }
       
  2344 
       
  2345     const TDesC& location(aEntry.ValueText(KMPXMediaGeneralUri));
       
  2346 
       
  2347     // Check DRM Only if we have a location
       
  2348     if (location != KNullDesC)
       
  2349         {
       
  2350         TUint drmAttributes(0);
       
  2351 
       
  2352         // Compact the attribute set
       
  2353         TInt count(aAttrs.Count());
       
  2354         for (TInt i = 0; i < count; ++i)
       
  2355             {
       
  2356             if (aAttrs[i].ContentId() == KMPXMediaIdDrm)
       
  2357                 {
       
  2358                 drmAttributes |= aAttrs[i].AttributeId();
       
  2359                 }
       
  2360             }
       
  2361 
       
  2362         // Set the correct attributes to media, only if requested
       
  2363         if (drmAttributes)
       
  2364             {
       
  2365             DoSetMediaDrmL(aEntry, drmAttributes, location);
       
  2366             }
       
  2367         }
       
  2368 
       
  2369     // Disable caching for any MediaL() returning song info.
       
  2370     TInt nonPermisAction( aEntry.ValueTObjectL<TInt>(KMPXMediaGeneralNonPermissibleActions));
       
  2371     nonPermisAction |= EMPXCache;
       
  2372 
       
  2373     aEntry.SetTObjectValueL<TMPXGeneralNonPermissibleActions>(
       
  2374                 KMPXMediaGeneralNonPermissibleActions, (TMPXGeneralNonPermissibleActions) nonPermisAction );
       
  2375     }
       
  2376 
       
  2377 // ----------------------------------------------------------------------------
       
  2378 // Find the collection details
       
  2379 // ----------------------------------------------------------------------------
       
  2380 //
       
  2381 void CMPXDbPlugin::DoHandleOtherMediaAttributesL(
       
  2382     const TArray<TMPXAttribute>& aAttrs,
       
  2383     const CMPXCollectionPath& aPath,
       
  2384     CMPXMedia& aMedia)
       
  2385     {
       
  2386     MPX_FUNC("CMPXDbPlugin::DoHandleOtherMediaAttributesL");
       
  2387 
       
  2388     TInt count(aAttrs.Count());
       
  2389     for (TInt i = 0; i < count; ++i)
       
  2390         {
       
  2391         if (aAttrs[i].ContentId() == KMPXMediaIdCollectionDetails)
       
  2392             {
       
  2393             TUint att(aAttrs[i].AttributeId());
       
  2394 
       
  2395             if (att & EMPXMediaColDetailNumberOfItems)
       
  2396                 {
       
  2397                 aMedia.SetTObjectValueL(KMPXMediaColDetailNumberOfItems,
       
  2398                     iDbHandler->NumberOfItemsL(EMPXSong));
       
  2399                 }
       
  2400             if (att & EMPXMediaColDetailDuration)
       
  2401                 {
       
  2402                 aMedia.SetTObjectValueL(KMPXMediaColDetailDuration,
       
  2403                     DoDurationL(aMedia, EMPXSong));
       
  2404                 }
       
  2405             if (att & EMPXMediaColTotalSize)
       
  2406                 {
       
  2407                 // todo
       
  2408                 TInt totalSize(0);
       
  2409                 aMedia.SetTObjectValueL(KMPXMediaColDetailTotalSize, totalSize);
       
  2410                 }
       
  2411             if (att & EMPXMediaLastRefreshed)
       
  2412                 {
       
  2413                 TTime lastRefreshed(iDbHandler->GetLastRefreshedTimeL());
       
  2414                 aMedia.SetTObjectValueL(KMPXMediaColDetailLastRefreshed,
       
  2415                     lastRefreshed.Int64());
       
  2416                 }
       
  2417             if (att & EMPXMediaColDetailDBCreated)
       
  2418                 {
       
  2419                 aMedia.SetTObjectValueL(KMPXMediaColDetailDBCreated,
       
  2420                     iDbHandler->DatabaseCreated());
       
  2421                 }
       
  2422             if (att & EMPXMediaColDetailDBCorrupted)
       
  2423                 {
       
  2424                 aMedia.SetTObjectValueL(KMPXMediaColDetailDBCorrupted,
       
  2425                     iDbHandler->IsDBCorruptedL());
       
  2426                 }
       
  2427             }
       
  2428         else if (aAttrs[i] == KMPXMediaGeneralPath)
       
  2429             {
       
  2430             aMedia.SetCObjectValueL(KMPXMediaGeneralPath,
       
  2431                 const_cast<CMPXCollectionPath*>(&aPath));
       
  2432             }
       
  2433         }
       
  2434     }
       
  2435 
       
  2436 // ----------------------------------------------------------------------------
       
  2437 // Remove an item from the collection database using the given path
       
  2438 // ----------------------------------------------------------------------------
       
  2439 //
       
  2440 CDesCArray* CMPXDbPlugin::DoRemoveL(
       
  2441     const CMPXCollectionPath& aPath,
       
  2442     CMPXMessageArray& aChangeMsgArray)
       
  2443     {
       
  2444     MPX_FUNC("CMPXDbPlugin::DoRemoveL");
       
  2445 
       
  2446     if (aPath.Levels() <= 1)
       
  2447         {
       
  2448         User::Leave(KErrNotSupported);
       
  2449         }
       
  2450 
       
  2451     // Return file path for deleted item(s)
       
  2452     //
       
  2453     CDesCArray* fp = new(ELeave) CDesCArrayFlat(1);
       
  2454     CleanupStack::PushL(fp);
       
  2455 
       
  2456     // Ids of the selected items
       
  2457     RArray<TMPXItemId> selections;
       
  2458     CleanupClosePushL(selections);
       
  2459     aPath.SelectionL(selections);
       
  2460 
       
  2461     switch (aPath.Id(1).iId2)
       
  2462         {
       
  2463         case EBrowseAll:
       
  2464             {
       
  2465             DoRemoveFromAllSongsL(aPath, selections.Array(), *fp, aChangeMsgArray);
       
  2466             }
       
  2467             break;
       
  2468 
       
  2469         case EBrowseArtist:
       
  2470             {
       
  2471             DoRemoveFromArtistsL(aPath, selections.Array(), *fp, aChangeMsgArray);
       
  2472             }
       
  2473             break;
       
  2474 
       
  2475         case EBrowseAlbum: // deliberate fall through
       
  2476         case EBrowseGenre: // deliberate fall through
       
  2477         case EBrowseComposer: // deliberate fall through
       
  2478             {
       
  2479             DoRemoveFromCategoriesL(aPath, selections.Array(),
       
  2480                 CategoryForBrowseType(static_cast<TMCBrowseType>(aPath.Id(1).iId2)), *fp, aChangeMsgArray);
       
  2481             }
       
  2482             break;
       
  2483 
       
  2484         case EBrowsePlaylist:
       
  2485             {
       
  2486             DoRemoveFromPlaylistsL(aPath, selections.Array(), *fp, aChangeMsgArray);
       
  2487             }
       
  2488             break;
       
  2489 
       
  2490         default:
       
  2491             {
       
  2492             User::Leave(KErrArgument);
       
  2493             }
       
  2494         } // end switch (aPath.Id(1))
       
  2495 
       
  2496     MPX_DEBUG2("CMPXDbPlugin::RemoveL itemId[%d]", aPath.Id(aPath.Levels() - 1).iId2);
       
  2497 
       
  2498     CleanupStack::PopAndDestroy( &selections );
       
  2499     CleanupStack::Pop(fp);
       
  2500 
       
  2501     return fp;
       
  2502     }
       
  2503 
       
  2504 // ----------------------------------------------------------------------------
       
  2505 // Remove an item from the collection database using the given media properties
       
  2506 // ----------------------------------------------------------------------------
       
  2507 //
       
  2508 void CMPXDbPlugin::DoRemoveL(
       
  2509     const CMPXMedia& aMedia,
       
  2510     TBool aDeleteRecord)
       
  2511     {
       
  2512     MPX_FUNC("CMPXDbPlugin::DoRemoveL(by media)");
       
  2513 
       
  2514     // Return deleted file paths to caller
       
  2515     CDesCArray* fp = new(ELeave) CDesCArrayFlat(1);
       
  2516     CleanupStack::PushL(fp);
       
  2517 
       
  2518     // a list of change event messages a result of the item being removed
       
  2519     CMPXMessageArray* itemChangedMessages = CMPXMediaArray::NewL();
       
  2520     CleanupStack::PushL(itemChangedMessages);
       
  2521 
       
  2522     TUint32 mediaId(0);
       
  2523 
       
  2524     // Removing a container of items
       
  2525     //
       
  2526     if (aMedia.IsSupported(KMPXMediaArrayContents))
       
  2527         {
       
  2528         MPX_DEBUG1("CMPXDbPlugin::RemoveL -- Removing a container of items");
       
  2529         const CMPXMediaArray* media = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  2530         if( !media )
       
  2531             {
       
  2532             User::Leave(KErrNoMemory);
       
  2533             }
       
  2534         const TInt mediaCount(media->Count());
       
  2535         for (TInt i = 0; i < mediaCount; ++i)
       
  2536             {
       
  2537             CMPXMedia* entry = media->AtL(i);
       
  2538             if (entry->IsSupported(KMPXMediaGeneralId))
       
  2539                 {
       
  2540                 mediaId = entry->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2541                 }
       
  2542             else if (entry->IsSupported(KMPXMediaGeneralUri))
       
  2543                 {
       
  2544                 const TDesC& uri = entry->ValueText(KMPXMediaGeneralUri);
       
  2545                 mediaId = iDbHandler->GetSongIdMatchingUriL(uri);
       
  2546                 }
       
  2547             else
       
  2548                 {
       
  2549                 // Unable to process this item
       
  2550                 continue;
       
  2551                 }
       
  2552 
       
  2553             iDbHandler->RemoveSongL(mediaId, *fp, *itemChangedMessages, aDeleteRecord);
       
  2554             }
       
  2555         }
       
  2556     // Removing an item with known item id
       
  2557     //
       
  2558     else if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  2559         {
       
  2560         MPX_DEBUG1("CMPXDbPlugin::RemoveL -- Removing an item by item id");
       
  2561         mediaId =  aMedia.ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  2562 
       
  2563         if (MPX_ITEM_CATEGORY(mediaId) != EMPXPlaylist)
       
  2564             {
       
  2565             iDbHandler->RemoveSongL(mediaId, *fp, *itemChangedMessages, aDeleteRecord);
       
  2566             }
       
  2567         else
       
  2568             {
       
  2569             iDbHandler->RemovePlaylistL(mediaId, *fp, *itemChangedMessages);
       
  2570             }
       
  2571         }
       
  2572     // Removing an item with known uri
       
  2573     //
       
  2574     else if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  2575         {
       
  2576         MPX_DEBUG1("CMPXDbPlugin::RemoveL -- Removing an item by uri");
       
  2577         TPtrC uri = aMedia.ValueText( KMPXMediaGeneralUri );
       
  2578 
       
  2579         TMPXGeneralCategory category =
       
  2580             aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  2581 
       
  2582         if (category == EMPXSong)
       
  2583             {
       
  2584             mediaId = iDbHandler->GetSongIdMatchingUriL(uri);
       
  2585             iDbHandler->RemoveSongL(mediaId, *fp, *itemChangedMessages, aDeleteRecord);
       
  2586             }
       
  2587         else if (category == EMPXPlaylist)
       
  2588             {
       
  2589             mediaId = iDbHandler->GetPlaylistIdMatchingUriL(uri);
       
  2590             iDbHandler->RemovePlaylistL(mediaId, *fp, *itemChangedMessages);
       
  2591             }
       
  2592 #ifdef ABSTRACTAUDIOALBUM_INCLUDED            
       
  2593         else if (category == EMPXAbstractAlbum )
       
  2594             {
       
  2595             mediaId = iDbHandler->GetAbstractAlbumIdMatchingUriL(uri);
       
  2596             iDbHandler->RemoveAbstractAlbumL(mediaId, *fp, *itemChangedMessages);            
       
  2597             }
       
  2598 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  2599         else
       
  2600             {
       
  2601             // otherwise unable to process this item
       
  2602             }
       
  2603         }
       
  2604     else
       
  2605         {
       
  2606         MPX_DEBUG1("CMPXDbPlugin::RemoveL -- Unknown item for removal");
       
  2607         User::Leave(KErrNotSupported);
       
  2608         }
       
  2609 
       
  2610     iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  2611 
       
  2612     // Removing an item always invalidates all songs.
       
  2613     //
       
  2614     MPXDbCommonUtil::AddItemChangedMessageL(*itemChangedMessages, EBrowseAll,
       
  2615                                             EMPXItemModified, EMPXCollection, KDBPluginUid);
       
  2616 
       
  2617     DoHandleChangeL(itemChangedMessages);
       
  2618 
       
  2619     CleanupStack::PopAndDestroy(itemChangedMessages);
       
  2620     CleanupStack::PopAndDestroy(fp);
       
  2621     }
       
  2622 
       
  2623 // ----------------------------------------------------------------------------
       
  2624 // Remove media by path through a command
       
  2625 // ----------------------------------------------------------------------------
       
  2626 //
       
  2627 void CMPXDbPlugin::DoRemovePathL(
       
  2628     CMPXCommand& aCmd)
       
  2629     {
       
  2630     MPX_FUNC("CMPXDbPlugin::DoRemovePathL(by command)");
       
  2631 
       
  2632     TInt removeError(KErrNone);
       
  2633     TBool removeCompleted(ETrue);
       
  2634 
       
  2635     if (!aCmd.IsSupported(KMPXCommandCollectionRemovePath) ||
       
  2636         !aCmd.IsSupported(KMPXCommandCollectionRemoveMediaCount))
       
  2637         {
       
  2638         removeError = KErrArgument;
       
  2639         }
       
  2640     else
       
  2641         {
       
  2642         CMPXCollectionPath* path =
       
  2643             aCmd.ValueCObjectL<CMPXCollectionPath>(KMPXCommandCollectionRemovePath);
       
  2644         CleanupStack::PushL(path);
       
  2645 
       
  2646         // in order to support cancel delete for a category, we need to adjust path. If
       
  2647         // the path ends in a category, retrieve all songs under the selected category
       
  2648         // and append a new level with all songs under the selected category
       
  2649         DoAppendLevelL(*path);
       
  2650 
       
  2651         CMPXCollectionPath* iterationPath = CMPXCollectionPath::NewL(*path);
       
  2652         CleanupStack::PushL(iterationPath);
       
  2653         iterationPath->ClearSelection();
       
  2654 
       
  2655         // indices of the selected items
       
  2656         TArray<TInt> selectionIndices = path->Selection();
       
  2657         TInt count(selectionIndices.Count());
       
  2658 
       
  2659         // number of media items to remove in this iteration
       
  2660         TInt removeCount = (aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionRemoveMediaCount));
       
  2661 
       
  2662         // remove all in one shot if removeCount is 0 or negative
       
  2663         if (removeCount <= 0)
       
  2664             {
       
  2665             removeCount = count;
       
  2666             }
       
  2667 
       
  2668         // If the given path contains multiple selections, remove the first n selected media
       
  2669         // and update the path so that client can use this path to call remove iteratively
       
  2670         // until all selections are processed
       
  2671         //
       
  2672         if (count)
       
  2673             {
       
  2674             for (TInt i = 0; i < removeCount; ++i)
       
  2675                 {
       
  2676                 TInt index(selectionIndices[i]);
       
  2677 
       
  2678                 MPX_DEBUG4(" path: selected item [index %d] [selectioncount %d] [remove count %d]", index, count, removeCount);
       
  2679 
       
  2680                 iterationPath->SelectL(index);
       
  2681                 path->Remove(index);
       
  2682                 }
       
  2683 
       
  2684             aCmd.SetCObjectValueL(KMPXCommandCollectionRemovePath, path);
       
  2685 
       
  2686             // indicate to the client that subsequent remove command is required
       
  2687             if ((count - removeCount) > 0)
       
  2688                 {
       
  2689                 removeCompleted = EFalse;
       
  2690                 }
       
  2691             }
       
  2692 
       
  2693         // Remove the media specified by the path
       
  2694         CDesCArray* fp(NULL);
       
  2695         TBool supressMsgs(EFalse);
       
  2696         CMPXMessageArray* msgAry(NULL);
       
  2697 
       
  2698         if (aCmd.IsSupported(KMPXCommandCollectionRemoveSuppressMsgs) &&
       
  2699             aCmd.ValueTObjectL<TBool>(KMPXCommandCollectionRemoveSuppressMsgs))
       
  2700             {
       
  2701             // Msgs are stored in the command
       
  2702             supressMsgs = ETrue;
       
  2703 
       
  2704             CMPXMessageArray* msgs( aCmd.Value<CMPXMessageArray>(KMPXCommandCollectionChangeMsgs) );
       
  2705             User::LeaveIfNull( msgs );
       
  2706             fp = DoRemoveL(*iterationPath, *msgs);
       
  2707             }
       
  2708         else
       
  2709             {
       
  2710             // Msgs will be sent after delete
       
  2711             msgAry = CMPXMessageArray::NewL();
       
  2712             CleanupStack::PushL(msgAry);
       
  2713             fp = DoRemoveL(*iterationPath, *msgAry);
       
  2714             }
       
  2715 
       
  2716         CleanupStack::PushL(fp);
       
  2717         if (fp->MdcaCount() > removeCount)
       
  2718             {
       
  2719             removeError = KErrCorrupt;
       
  2720             }
       
  2721         CleanupStack::PopAndDestroy(fp);
       
  2722 
       
  2723         if (!supressMsgs)
       
  2724             {
       
  2725             // Send Change Messages
       
  2726             iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  2727             DoHandleChangeL(msgAry);
       
  2728             CleanupStack::PopAndDestroy(msgAry);
       
  2729             }
       
  2730 
       
  2731         // Cleanup
       
  2732         CleanupStack::PopAndDestroy(iterationPath);
       
  2733         CleanupStack::PopAndDestroy(path);
       
  2734         }
       
  2735 
       
  2736     // mandatory return parameters
       
  2737     aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionRemoveError, removeError);
       
  2738     aCmd.SetTObjectValueL<TBool>(KMPXCommandCollectionRemoveCompleted, removeCompleted);
       
  2739     }
       
  2740 
       
  2741 // ----------------------------------------------------------------------------
       
  2742 // Remove media by CMPXMedia through a command
       
  2743 // ----------------------------------------------------------------------------
       
  2744 //
       
  2745 void CMPXDbPlugin::DoRemoveMediaL(
       
  2746     CMPXCommand& aCmd)
       
  2747     {
       
  2748     MPX_FUNC("CMPXDbPlugin::DoRemoveMediaL(by command)");
       
  2749 
       
  2750     TInt error(KErrArgument);
       
  2751 
       
  2752     if (aCmd.IsSupported(KMPXCommandCollectionRemoveMedia))
       
  2753         {
       
  2754         CMPXMedia* media = aCmd.ValueCObjectL<CMPXMedia>(KMPXCommandCollectionRemoveMedia);
       
  2755         CleanupStack::PushL(media);
       
  2756 
       
  2757         MPX_TRAP(error, DoRemoveL(*media,
       
  2758             aCmd.ValueTObjectL<TBool>(KMPXCommandCollectionRemoveMediaDeleteRecord)));
       
  2759 
       
  2760         CleanupStack::PopAndDestroy(media);
       
  2761         }
       
  2762 
       
  2763     aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionRemoveMediaError, error);
       
  2764     }
       
  2765 
       
  2766 // ----------------------------------------------------------------------------
       
  2767 // Remove a media/media items from All Songs view
       
  2768 // ----------------------------------------------------------------------------
       
  2769 //
       
  2770 void CMPXDbPlugin::DoRemoveFromAllSongsL(
       
  2771     const CMPXCollectionPath& aPath,
       
  2772     const TArray<TMPXItemId>& aSelections,
       
  2773     CDesCArray& aUriArray,
       
  2774     CMPXMessageArray& aItemChangedMessages)
       
  2775     {
       
  2776     MPX_FUNC("CMPXDbPlugin::DoRemoveFromAllSongsL");
       
  2777 
       
  2778     switch (aPath.Levels())
       
  2779         {
       
  2780         case 2:
       
  2781             {
       
  2782             // when the collection is removed, it's intended not to delete the files
       
  2783             iDbHandler->RemoveEntireCollectionL();
       
  2784             }
       
  2785             break;
       
  2786 
       
  2787         case 3:
       
  2788             {
       
  2789             TInt count(aSelections.Count());
       
  2790             if (count)
       
  2791                 {
       
  2792                 for (TInt i = 0; i < count; ++i)
       
  2793                     {
       
  2794                     iDbHandler->RemoveSongL(aSelections[i].iId2, aUriArray, aItemChangedMessages);
       
  2795                     } // end for
       
  2796                 }
       
  2797             else
       
  2798                 {
       
  2799                 iDbHandler->RemoveSongL(aPath.Id(aPath.Levels() - 1).iId2, aUriArray,
       
  2800                      aItemChangedMessages);
       
  2801                 }
       
  2802             }
       
  2803             break;
       
  2804 
       
  2805         default:
       
  2806             {
       
  2807             MPX_DEBUG2("CMPXDbPlugin_DoRemoveFromAllSongsL: Invalid levels[%d]", aPath.Levels());
       
  2808             User::Leave(KErrNotSupported);
       
  2809             }
       
  2810         }
       
  2811     }
       
  2812 
       
  2813 // ----------------------------------------------------------------------------
       
  2814 // Remove a media/media items from Artists view
       
  2815 // ----------------------------------------------------------------------------
       
  2816 //
       
  2817 void CMPXDbPlugin::DoRemoveFromArtistsL(
       
  2818     const CMPXCollectionPath& aPath,
       
  2819     const TArray<TMPXItemId>& aSelections,
       
  2820     CDesCArray& aUriArray,
       
  2821     CMPXMessageArray& aItemChangedMessages)
       
  2822     {
       
  2823     MPX_FUNC("CMPXDbPlugin::DoRemoveFromArtistsL");
       
  2824 
       
  2825     TInt levels(aPath.Levels());
       
  2826     if (levels == 2)
       
  2827         {
       
  2828         // when the collection is removed, it's intended not to delete the files
       
  2829         iDbHandler->RemoveEntireCollectionL();
       
  2830         }
       
  2831     else
       
  2832         {
       
  2833         TInt count(aSelections.Count());
       
  2834         if (count)
       
  2835             {
       
  2836             for (TInt i = 0; i < count; ++i)
       
  2837                 {
       
  2838                 RemoveFromArtistsL(aPath, aSelections[i].iId2, aUriArray, aItemChangedMessages);
       
  2839                 }
       
  2840             }
       
  2841         else
       
  2842             {
       
  2843             RemoveFromArtistsL(aPath, aPath.Id(levels - 1).iId2, aUriArray, aItemChangedMessages);
       
  2844             }
       
  2845         }
       
  2846 
       
  2847     MPX_DEBUG2("CMPXDbPlugin__RemoveL__EBrowseArtist: levels[%d]", levels);
       
  2848     }
       
  2849 
       
  2850 // ----------------------------------------------------------------------------
       
  2851 // Remove a media item from Artists view
       
  2852 // ----------------------------------------------------------------------------
       
  2853 //
       
  2854 void CMPXDbPlugin::RemoveFromArtistsL(
       
  2855     const CMPXCollectionPath& aPath,
       
  2856     TUint32 aItemId,
       
  2857     CDesCArray& aUriArray,
       
  2858     CMPXMessageArray& aItemChangedMessages)
       
  2859     {
       
  2860     MPX_FUNC("CMPXDbPlugin::RemoveFromArtistsL");
       
  2861 
       
  2862     switch (aPath.Levels())
       
  2863         {
       
  2864         case 3:
       
  2865             {
       
  2866             iDbHandler->RemoveSongsMatchingCategoryL(EMPXArtist, aItemId, aUriArray, aItemChangedMessages);
       
  2867             break;
       
  2868             }
       
  2869         case 4:
       
  2870             {
       
  2871             // remove the songs for the artist and album
       
  2872             iDbHandler->RemoveSongsMatchingArtistAndAlbumL(aPath.Id(aPath.Levels() - 2), aItemId,
       
  2873                 aUriArray, aItemChangedMessages);
       
  2874             break;
       
  2875             }
       
  2876         case 5:
       
  2877             {
       
  2878             iDbHandler->RemoveSongL(aItemId, aUriArray, aItemChangedMessages);
       
  2879             break;
       
  2880             }
       
  2881         default:
       
  2882             {
       
  2883             User::Leave(KErrArgument);
       
  2884             }
       
  2885         }
       
  2886     }
       
  2887 
       
  2888 // ----------------------------------------------------------------------------
       
  2889 // Remove a media/media items from Albums/Genres/Composers view
       
  2890 // ----------------------------------------------------------------------------
       
  2891 //
       
  2892 void CMPXDbPlugin::DoRemoveFromCategoriesL(
       
  2893     const CMPXCollectionPath& aPath,
       
  2894     const TArray<TMPXItemId>& aSelections,
       
  2895     TMPXGeneralCategory aCategory,
       
  2896     CDesCArray& aUriArray,
       
  2897     CMPXMessageArray& aItemChangedMessages)
       
  2898     {
       
  2899     MPX_FUNC("CMPXDbPlugin::DoRemoveFromCategoriesL");
       
  2900 
       
  2901     TInt levels(aPath.Levels());
       
  2902     if (levels == 2)
       
  2903         {
       
  2904         // when the collection is removed, it's intended not to delete the files
       
  2905         iDbHandler->RemoveEntireCollectionL();
       
  2906         }
       
  2907     else
       
  2908         {
       
  2909         TInt count(aSelections.Count());
       
  2910         if (count)
       
  2911             {
       
  2912             for (TInt i = 0; i < count; ++i)
       
  2913                 {
       
  2914                 RemoveFromCategoriesL(aPath, aSelections[i].iId2, aCategory,
       
  2915                     aUriArray, aItemChangedMessages);
       
  2916                 }
       
  2917             }
       
  2918         else
       
  2919             {
       
  2920             RemoveFromCategoriesL(aPath, aPath.Id(levels - 1).iId2, aCategory,
       
  2921                 aUriArray, aItemChangedMessages);
       
  2922             }
       
  2923         }
       
  2924 
       
  2925     MPX_DEBUG2("CMPXDbPlugin__RemoveL__EBrowseAlbum: levels[%d]", levels);
       
  2926     }
       
  2927 
       
  2928 // ----------------------------------------------------------------------------
       
  2929 // Remove a media item from Albums/Genres/Composers view
       
  2930 // ----------------------------------------------------------------------------
       
  2931 //
       
  2932 void CMPXDbPlugin::RemoveFromCategoriesL(
       
  2933     const CMPXCollectionPath& aPath,
       
  2934     TUint32 aItemId,
       
  2935     TMPXGeneralCategory aCategory,
       
  2936     CDesCArray& aUriArray,
       
  2937     CMPXMessageArray& aItemChangedMessages)
       
  2938     {
       
  2939     MPX_FUNC("CMPXDbPlugin::RemoveFromCategoriesL");
       
  2940 
       
  2941     switch (aPath.Levels())
       
  2942         {
       
  2943         case 3:
       
  2944             {
       
  2945             iDbHandler->RemoveSongsMatchingCategoryL(aCategory, aItemId, aUriArray,
       
  2946                 aItemChangedMessages);
       
  2947             break;
       
  2948             }
       
  2949         case 4:
       
  2950             {
       
  2951             iDbHandler->RemoveSongL(aItemId, aUriArray, aItemChangedMessages);
       
  2952             break;
       
  2953             }
       
  2954         default:
       
  2955             {
       
  2956             User::Leave(KErrArgument);
       
  2957             }
       
  2958         }
       
  2959     }
       
  2960 
       
  2961 // ----------------------------------------------------------------------------
       
  2962 // Remove one or multiple media items from Playlists view
       
  2963 // ----------------------------------------------------------------------------
       
  2964 //
       
  2965 void CMPXDbPlugin::DoRemoveFromPlaylistsL(
       
  2966     const CMPXCollectionPath& aPath,
       
  2967     const TArray<TMPXItemId>& aSelections,
       
  2968     CDesCArray& aUriArray,
       
  2969     CMPXMessageArray& aItemChangedMessages)
       
  2970     {
       
  2971     MPX_FUNC("CMPXDbPlugin::DoRemoveFromPlaylistsL");
       
  2972 
       
  2973     TInt levels(aPath.Levels());
       
  2974 
       
  2975     // all playlists
       
  2976     if (levels == 2)
       
  2977         {
       
  2978         // when the collection is removed, it's intended not to delete the files
       
  2979         iDbHandler->RemoveAllPlaylistsL();
       
  2980         }
       
  2981     else
       
  2982         {
       
  2983         TArray<TInt> selectionIndices = aPath.Selection();
       
  2984         TInt count(selectionIndices.Count());
       
  2985 
       
  2986         // multiple selections
       
  2987         if (count)
       
  2988             {
       
  2989             for (TInt i = (count - 1); i >= 0; --i)
       
  2990                 {
       
  2991                 RemoveFromPlaylistsL(aPath, aSelections[i], selectionIndices[i],
       
  2992                     aUriArray, aItemChangedMessages);
       
  2993                 }
       
  2994             }
       
  2995         // else no selection
       
  2996         else
       
  2997             {
       
  2998             RemoveFromPlaylistsL(aPath, aPath.IdOfIndex(aPath.Index()), aPath.Index(),
       
  2999                 aUriArray, aItemChangedMessages);
       
  3000             }
       
  3001         }
       
  3002 
       
  3003     MPX_DEBUG2("CMPXDbPlugin__RemoveL__EBrowsePlaylist: levels[%d]", levels);
       
  3004     }
       
  3005 
       
  3006 // ----------------------------------------------------------------------------
       
  3007 // Remove a media item from Playlists view
       
  3008 // ----------------------------------------------------------------------------
       
  3009 //
       
  3010 void CMPXDbPlugin::RemoveFromPlaylistsL(
       
  3011     const CMPXCollectionPath& aPath,
       
  3012     const TMPXItemId& aItemId,
       
  3013     TInt aIndex,
       
  3014     CDesCArray& aUriArray,
       
  3015     CMPXMessageArray& aItemChangedMessages)
       
  3016     {
       
  3017     MPX_FUNC("CMPXDbPlugin::RemoveFromPlaylistsL");
       
  3018 
       
  3019     switch (aPath.Levels())
       
  3020         {
       
  3021         case 3:
       
  3022             {
       
  3023             iDbHandler->RemovePlaylistL(aItemId.iId2, aUriArray, aItemChangedMessages);
       
  3024             break;
       
  3025             }
       
  3026         case 4:
       
  3027             {
       
  3028             if ( !iDbHandler->InTransaction() )
       
  3029                 {
       
  3030                 iDbHandler->BeginTransactionL();
       
  3031                 }
       
  3032             iDbHandler->RemoveSongFromPlaylistL(aPath.Id(aPath.Levels() - 2).iId2, aItemId,
       
  3033                 aIndex, aItemChangedMessages);
       
  3034             break;
       
  3035             }
       
  3036         default:
       
  3037             {
       
  3038             User::Leave(KErrArgument);
       
  3039             }
       
  3040         }
       
  3041     }
       
  3042 
       
  3043 // ----------------------------------------------------------------------------
       
  3044 // Retrieve URIs associated with this file path for file deletion
       
  3045 // ----------------------------------------------------------------------------
       
  3046 //
       
  3047 void CMPXDbPlugin::DoRetrieveUriForDeletionL(
       
  3048     CMPXCommand& aCmd)
       
  3049     {
       
  3050     MPX_FUNC("CMPXDbPlugin::DoRetrieveUriForDeletionL");
       
  3051 
       
  3052     // initialize mandatory return parameters
       
  3053     aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionRetrieveUriError, KErrNone);
       
  3054 
       
  3055     if (!aCmd.IsSupported(KMPXCommandCollectionRetrievePath))
       
  3056         {
       
  3057         aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionRetrieveUriError, KErrArgument);
       
  3058         }
       
  3059     else
       
  3060         {
       
  3061         CMPXCollectionPath* path = aCmd.ValueCObjectL<CMPXCollectionPath>(KMPXCommandCollectionRetrievePath);
       
  3062         CleanupStack::PushL(path);
       
  3063         if (iFirstDeleteStep )
       
  3064             {
       
  3065             iSelections.Reset( );
       
  3066         // in order to support cancel delete for a category, we need to adjust path. If
       
  3067         // the path ends in a category, retrieve all songs under the selected category
       
  3068         // and append a new level with all songs under the selected category
       
  3069         DoAppendLevelL(*path);
       
  3070 
       
  3071         // Ids of the selected items
       
  3072             path->SelectionL(iSelections );
       
  3073 
       
  3074         // single selection
       
  3075             if (iSelections.Count()== 0 )
       
  3076                 {
       
  3077                 iSelections.AppendL(path->Id (path->Levels()- 1 ) );
       
  3078                 }
       
  3079             }
       
  3080 
       
  3081         CDesCArray* fp = new(ELeave) CDesCArrayFlat(4);
       
  3082         CleanupStack::PushL(fp);
       
  3083 
       
  3084         TInt count(iSelections.Count());
       
  3085         TInt itemCount = count > KIncrementalDeleteCount ? KIncrementalDeleteCount : count;
       
  3086         for (TInt i = 0; i < itemCount; ++i )
       
  3087             {
       
  3088             // do not report song URIs if collection path is for songs within a playlist, i.e.
       
  3089             // EBrowsePlaylist and level 4, because client should not be deleting those song
       
  3090             // files
       
  3091             if (path->Id(1) != EBrowsePlaylist || path->Levels() !=4)
       
  3092                 {
       
  3093                 HBufC * uri = iDbHandler->GetUriMatchingIdL (iSelections[0].iId2 );
       
  3094                 CleanupStack::PushL(uri);
       
  3095                 fp->AppendL(*uri);
       
  3096                 CleanupStack::PopAndDestroy(uri);
       
  3097                 }
       
  3098             iSelections.Remove(0);
       
  3099             }
       
  3100 
       
  3101         aCmd.SetNoNewLCObjectL(KMPXCommandCollectionRetrieveMediaUriArray, fp);
       
  3102         if (iFirstDeleteStep)
       
  3103             {
       
  3104         aCmd.SetCObjectValueL(KMPXCommandCollectionRetrievePath, path);
       
  3105             }
       
  3106 
       
  3107         CleanupStack::PopAndDestroy(fp);
       
  3108         CleanupStack::PopAndDestroy(path);
       
  3109         }
       
  3110     }
       
  3111 
       
  3112 // ----------------------------------------------------------------------------
       
  3113 // Cleanup deleted records
       
  3114 // ----------------------------------------------------------------------------
       
  3115 //
       
  3116 void CMPXDbPlugin::CleanupDeletedRecordsL(
       
  3117     CMPXCommand& aCmd)
       
  3118     {
       
  3119     MPX_FUNC("CMPXDbPlugin::CleanupDeletedRecordsL");
       
  3120 
       
  3121     MPX_TRAPD(error, iDbHandler->CleanupDeletedRecordsL());
       
  3122     aCmd.SetTObjectValueL<TInt>(KMPXCommandCollectionCleanupError, error);
       
  3123     }
       
  3124 
       
  3125 // ----------------------------------------------------------------------------
       
  3126 // Find the duration
       
  3127 // ----------------------------------------------------------------------------
       
  3128 //
       
  3129 TInt CMPXDbPlugin::DoDurationL(
       
  3130     CMPXMedia& aMedia,
       
  3131     TMPXGeneralCategory aFirstCat,
       
  3132     TMPXItemId aId,
       
  3133     TMPXGeneralCategory aSecondCat,
       
  3134     TMPXItemId aSubId)
       
  3135     {
       
  3136     MPX_FUNC("CMPXDbPlugin::DoDurationL");
       
  3137 
       
  3138     TInt duration(0);
       
  3139 
       
  3140     switch (aFirstCat)
       
  3141         {
       
  3142         case EMPXSong:
       
  3143             {
       
  3144             duration = iDbHandler->GetAllSongsDurationL();
       
  3145             break;
       
  3146             }
       
  3147         case EMPXAlbum:
       
  3148             {
       
  3149             duration = iDbHandler->GetAlbumDurationL(aId.iId2);
       
  3150             break;
       
  3151             }
       
  3152         case EMPXComposer:
       
  3153             {
       
  3154             duration = iDbHandler->GetComposerDurationL(aId.iId2);
       
  3155             break;
       
  3156             }
       
  3157         case EMPXGenre:
       
  3158             {
       
  3159             duration = iDbHandler->GetGenreDurationL(aId.iId2);
       
  3160             break;
       
  3161             }
       
  3162         case EMPXArtist:
       
  3163             {
       
  3164             if (aSecondCat == EMPXAlbum)
       
  3165                 {
       
  3166                 duration = iDbHandler->GetArtistAlbumDurationL(aId.iId2, aSubId.iId2);
       
  3167                 }
       
  3168             else
       
  3169                 {
       
  3170                 duration = iDbHandler->GetArtistDurationL(aId.iId2);
       
  3171                 }
       
  3172             break;
       
  3173             }
       
  3174         case EMPXPlaylist:
       
  3175             {
       
  3176             duration = iDbHandler->GetPlaylistDurationL(aId.iId2);
       
  3177             break;
       
  3178             }
       
  3179         default:
       
  3180             {
       
  3181             User::Leave(KErrNotSupported);
       
  3182             }
       
  3183         }
       
  3184 
       
  3185     aMedia.SetTObjectValueL<TInt>(KMPXMediaGeneralDuration, duration);
       
  3186     return duration;
       
  3187     }
       
  3188 
       
  3189 // ----------------------------------------------------------------------------
       
  3190 // Append a level to a collection path and set selection to the first item
       
  3191 // ----------------------------------------------------------------------------
       
  3192 //
       
  3193 TInt CMPXDbPlugin::DoAppendLevelL(
       
  3194     CMPXCollectionPath& aPath,
       
  3195     CMPXMedia& aMedia )
       
  3196     {
       
  3197     MPX_FUNC("CMPXDbPlugin::DoAppendLevelL");
       
  3198 
       
  3199     RArray<TMPXItemId> ids;
       
  3200     CleanupClosePushL(ids);
       
  3201 
       
  3202     // Extract media array, and get all item ids
       
  3203     //
       
  3204     const CMPXMediaArray* mediaArray = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3205     if( !mediaArray )
       
  3206         {
       
  3207         User::Leave( KErrNoMemory );
       
  3208         }
       
  3209 
       
  3210     TInt count(mediaArray->Count());
       
  3211     if (count >= 0)
       
  3212         {
       
  3213         for (TInt i = 0; i < count; ++i)
       
  3214             {
       
  3215             TMPXItemId id = mediaArray->AtL(i)->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId);
       
  3216             ids.AppendL(id);
       
  3217             }
       
  3218 
       
  3219         // Put item id array into the path and select the first one
       
  3220         aPath.AppendL(ids.Array());
       
  3221         if (count > 0)
       
  3222             {
       
  3223             aPath.Set(0);
       
  3224             }
       
  3225         }
       
  3226 
       
  3227     CleanupStack::PopAndDestroy(&ids);
       
  3228     return count;
       
  3229     }
       
  3230 
       
  3231 // ----------------------------------------------------------------------------
       
  3232 // Append a level to a collection path and set selection to all songs under the
       
  3233 // selected category/categories
       
  3234 // ----------------------------------------------------------------------------
       
  3235 //
       
  3236 void CMPXDbPlugin::DoAppendLevelL(
       
  3237     CMPXCollectionPath& aPath)
       
  3238     {
       
  3239     MPX_FUNC("CMPXDbPlugin::DoAppendLevelL");
       
  3240 
       
  3241     TMPXItemId contextId(aPath.Id(1));
       
  3242     TInt levels(aPath.Levels());
       
  3243 
       
  3244     if ((contextId == EBrowseAll) ||
       
  3245         (contextId == EBrowsePlaylist))
       
  3246         {
       
  3247         return;
       
  3248         }
       
  3249     else if (levels == 3 || (levels == 4 && contextId == EBrowseArtist))
       
  3250         {
       
  3251         // retrieve songs in the selected category
       
  3252         //
       
  3253         CMPXMediaArray* songs = CMPXMediaArray::NewL();
       
  3254         CleanupStack::PushL(songs);
       
  3255 
       
  3256         RArray<TMPXAttribute> attributes;
       
  3257         CleanupClosePushL(attributes);
       
  3258         attributes.AppendL(KMPXMediaGeneralId);
       
  3259 
       
  3260         // Ids of the selected items
       
  3261         RArray<TMPXItemId> selections;
       
  3262         CleanupClosePushL(selections);
       
  3263         aPath.SelectionL(selections);
       
  3264 
       
  3265         // single selection
       
  3266         if (selections.Count() == 0)
       
  3267             {
       
  3268             selections.AppendL(aPath.Id(aPath.Levels() - 1));
       
  3269             }
       
  3270 
       
  3271         TInt count(selections.Count());
       
  3272 
       
  3273         // all songs for the selected artist
       
  3274         if (contextId == EBrowseArtist && levels == 3)
       
  3275             {
       
  3276             for (TInt i = 0; i < count; ++i)
       
  3277                 {
       
  3278                 iDbHandler->GetSongsMatchingArtistL(selections[i].iId2, attributes.Array(), songs);
       
  3279                 }
       
  3280             if (songs->Count())
       
  3281                 {
       
  3282                 aPath.AppendL(selections.Array());
       
  3283                 }
       
  3284             }
       
  3285 
       
  3286         // all songs for the selected artist in the specified album
       
  3287         else if ((contextId == EBrowseArtist) && (levels == 4))
       
  3288             {
       
  3289             for (TInt i = 0; i < count; ++i)
       
  3290                 {
       
  3291                 if (aPath.Id(2) == aPath.Id(3))
       
  3292                     {
       
  3293                     iDbHandler->GetSongsMatchingArtistL(aPath.Id(3).iId2,
       
  3294                         attributes.Array(), songs);
       
  3295                     }
       
  3296                 else
       
  3297                     {
       
  3298                     iDbHandler->GetSongsMatchingArtistAndAlbumL(aPath.Id(aPath.Levels() - 2),
       
  3299                         selections[i].iId2, attributes.Array(), songs);
       
  3300                     }
       
  3301                 }
       
  3302             }
       
  3303 
       
  3304          // all songs for the selected album
       
  3305         else if (contextId == EBrowseAlbum && levels == 3)
       
  3306             {
       
  3307             for (TInt i = 0; i < count; ++i)
       
  3308                 {
       
  3309                 iDbHandler->GetSongsMatchingAlbumL(selections[i], attributes.Array(), songs);
       
  3310                 }
       
  3311             }
       
  3312 
       
  3313         // all songs for the selected genre
       
  3314         else if (contextId == EBrowseGenre && levels == 3)
       
  3315             {
       
  3316             for (TInt i = 0; i < count; ++i)
       
  3317                 {
       
  3318                 iDbHandler->GetSongsMatchingGenreL(selections[i], attributes.Array(), songs);
       
  3319                 }
       
  3320             }
       
  3321 
       
  3322         // all songs for the selected composer
       
  3323         else if (contextId == EBrowseComposer && levels == 3)
       
  3324             {
       
  3325             for (TInt i = 0; i < count; ++i)
       
  3326                 {
       
  3327                 iDbHandler->GetSongsMatchingComposerL(selections[i], attributes.Array(), songs);
       
  3328                 }
       
  3329             }
       
  3330         else
       
  3331             {
       
  3332             // else do nothing
       
  3333             }
       
  3334 
       
  3335         CleanupStack::PopAndDestroy(&selections);
       
  3336         CleanupStack::PopAndDestroy(&attributes);
       
  3337 
       
  3338         // transform from CMPXMediaArray to RArray
       
  3339         RArray<TMPXItemId> songIds;
       
  3340         CleanupClosePushL(songIds);
       
  3341 
       
  3342         TInt songCount(songs->Count());
       
  3343         for (TInt i = 0; i < songCount; ++i)
       
  3344             {
       
  3345             CMPXMedia* song = (*songs)[i];
       
  3346 
       
  3347             if (song->IsSupported(KMPXMediaGeneralId))
       
  3348                 {
       
  3349                 songIds.AppendL(song->ValueTObjectL<TMPXItemId>(KMPXMediaGeneralId));
       
  3350                 }
       
  3351             }
       
  3352 
       
  3353         // modify the collection path. append another level with all songs under the selected
       
  3354         // category/categories selected
       
  3355         songCount = songIds.Count();
       
  3356 
       
  3357         if (songCount)
       
  3358             {
       
  3359             aPath.ClearSelection();
       
  3360             aPath.AppendL(songIds.Array());
       
  3361 
       
  3362             // select all
       
  3363             for (TInt i = 0; i < songCount; ++i)
       
  3364                 {
       
  3365                 aPath.SelectL(songIds[i]);
       
  3366                 }
       
  3367             }
       
  3368 
       
  3369         CleanupStack::PopAndDestroy(&songIds);
       
  3370         CleanupStack::PopAndDestroy(songs);
       
  3371         }
       
  3372     else
       
  3373         {
       
  3374         // do nothing
       
  3375         }
       
  3376     }
       
  3377 
       
  3378 // ----------------------------------------------------------------------------
       
  3379 // Execute an Add task step
       
  3380 // ----------------------------------------------------------------------------
       
  3381 //
       
  3382 TBool CMPXDbPlugin::DoAddAsyncL()
       
  3383     {
       
  3384     MPX_FUNC("CMPXDbPlugin::DoAddAsyncL");
       
  3385 
       
  3386     TBool done(EFalse);
       
  3387     const CMPXMedia* task = (iActiveTask->GetCommand().Value<CMPXMedia>(KMPXCommandColAddMedia));
       
  3388     if( !task )
       
  3389         {
       
  3390         User::Leave(KErrNoMemory);
       
  3391         }
       
  3392 
       
  3393     CMPXMessageArray& msgArray = iActiveTask->GetChangeMessages();
       
  3394 
       
  3395     if (!task->IsSupported(KMPXMediaGeneralType))
       
  3396         {
       
  3397         User::Leave(KErrArgument);
       
  3398         }
       
  3399 
       
  3400     // Group of items or a single item
       
  3401     //
       
  3402     if (task->ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) == EMPXGroup)
       
  3403         {
       
  3404         if (!task->IsSupported(KMPXMediaArrayContents))
       
  3405             {
       
  3406             User::Leave(KErrArgument);
       
  3407             }
       
  3408 
       
  3409         CMPXMediaArray* ary = task->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3410         User::LeaveIfNull(ary);
       
  3411         TInt step( iActiveTask->GetStep() );
       
  3412         DoAddItemL( *ary->AtL(step), msgArray );
       
  3413 
       
  3414         if (++step == ary->Count())
       
  3415             {
       
  3416             done = ETrue;
       
  3417             }
       
  3418         }
       
  3419     else // type == EMPXItem
       
  3420         {
       
  3421         TUint32 item = DoAddItemL( *task, msgArray );
       
  3422         iActiveTask->GetCommand().SetTObjectValueL<TMPXItemId>( KMPXCommandColAddRtnId, item);
       
  3423         done = ETrue;
       
  3424         }
       
  3425 
       
  3426     iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  3427     return done;
       
  3428     }
       
  3429 
       
  3430 // ----------------------------------------------------------------------------
       
  3431 // Add an item to the collection
       
  3432 // ----------------------------------------------------------------------------
       
  3433 //
       
  3434 TUint32 CMPXDbPlugin::DoAddL(
       
  3435     const CMPXMedia& aMedia)
       
  3436     {
       
  3437     MPX_FUNC("CMPXDbPlugin::DoAddL");
       
  3438 
       
  3439     if (!aMedia.IsSupported(KMPXMediaGeneralType))
       
  3440         {
       
  3441         User::Leave(KErrArgument);
       
  3442         }
       
  3443 
       
  3444     TUint32 itemId(0);
       
  3445     CMPXMessageArray* changeMsgAry = CMPXMessageArray::NewL();
       
  3446     CleanupStack::PushL(changeMsgAry);
       
  3447 
       
  3448 	// start a transaction here
       
  3449 	if (!iDbHandler->InTransaction())
       
  3450 		{
       
  3451 		iDbHandler->BeginTransactionL();
       
  3452 		}
       
  3453 
       
  3454     // Group of items
       
  3455     if (aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) == EMPXGroup)
       
  3456         {
       
  3457         CMPXMediaArray* array = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3458         User::LeaveIfNull( array );
       
  3459 
       
  3460         TInt count(array->Count());
       
  3461         for (TInt i = 0; i < count; ++i)
       
  3462             {
       
  3463             // ETrue indicates we are batch committing the songs.
       
  3464             // This parameter is only used for the use case of adding
       
  3465             // thousands of songs at a time.
       
  3466             DoAddItemL(*array->AtL(i), *changeMsgAry, ETrue);
       
  3467             }
       
  3468         }
       
  3469     else // single item
       
  3470         {
       
  3471         itemId = DoAddItemL(aMedia, *changeMsgAry);
       
  3472         }
       
  3473 
       
  3474 	// end transaction here.
       
  3475 	iDbHandler->EndTransactionL(KErrNone);
       
  3476 
       
  3477     iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  3478     DoHandleChangeL(changeMsgAry);
       
  3479     CleanupStack::PopAndDestroy(changeMsgAry);
       
  3480 
       
  3481     return itemId;
       
  3482     }
       
  3483 
       
  3484 // ----------------------------------------------------------------------------------------------------------
       
  3485 // Add an item to the collection
       
  3486 // ----------------------------------------------------------------------------------------------------------
       
  3487 //
       
  3488 TUint32 CMPXDbPlugin::DoAddItemL(
       
  3489     const CMPXMedia& aMedia,
       
  3490     CMPXMessageArray& aMessageArray,
       
  3491     TBool aBatchCommit)
       
  3492     {
       
  3493     MPX_FUNC("CMPXDbPlugin::DoAddItemL");
       
  3494 
       
  3495     TUint32 itemId(0);
       
  3496     if (!aMedia.IsSupported(KMPXMediaGeneralCategory))
       
  3497         {
       
  3498         User::Leave(KErrArgument);
       
  3499         }
       
  3500 
       
  3501     switch (aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory))
       
  3502         {
       
  3503         case EMPXPlaylist:
       
  3504             {
       
  3505             if (!aMedia.IsSupported(KMPXMediaArrayContents))
       
  3506                 {
       
  3507                 User::Leave(KErrArgument);
       
  3508                 }
       
  3509 
       
  3510             if (aMedia.IsSupported(KMPXMediaGeneralId))
       
  3511                 {
       
  3512                 itemId = iDbHandler->AddSongToPlaylistL(aMedia);
       
  3513                 MPXDbCommonUtil::AddItemChangedMessageL(aMessageArray, itemId, EMPXItemModified,
       
  3514                     EMPXPlaylist, KDBPluginUid);
       
  3515                 }
       
  3516             else if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  3517                 {
       
  3518                 itemId = iDbHandler->AddPlaylistL(aMedia);
       
  3519                 MPXDbCommonUtil::AddItemChangedMessageL(aMessageArray, EBrowsePlaylist, EMPXItemInserted,
       
  3520                     EMPXPlaylist, KDBPluginUid);
       
  3521                 }
       
  3522             else
       
  3523                 {
       
  3524                 User::Leave(KErrArgument);
       
  3525                 }
       
  3526             }
       
  3527             break;
       
  3528 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  3529        case EMPXAbstractAlbum:
       
  3530             {
       
  3531             if (aMedia.IsSupported(KMPXMediaGeneralUri))
       
  3532                 { 
       
  3533                    
       
  3534                 itemId = iDbHandler->AddAbstractAlbumL(aMedia, &aMessageArray);
       
  3535             
       
  3536                 if ( aMedia.IsSupported(KMPXMediaArrayContents))
       
  3537                     {
       
  3538                     //need to update songs information to music table           
       
  3539                     CMPXMediaArray* array = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);                        
       
  3540                     if (array->Count())            
       
  3541                         {                  
       
  3542                         iDbHandler->UpdateAbstractAlbumSongsL(aMedia, aMessageArray);
       
  3543                         }
       
  3544                     }
       
  3545                 }
       
  3546             else
       
  3547                 {
       
  3548                 User::Leave(KErrArgument);
       
  3549                 }
       
  3550             }
       
  3551             break;
       
  3552 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  3553         case EMPXSong:
       
  3554             {
       
  3555             // For the use case of adding thousands of songs at once,
       
  3556             // we do not create a new database transaction for each song; 
       
  3557             // Instead DoAddL() will batch 100 songs under a single transaction.
       
  3558             // This enhancement improves performance with MMC-based databases.
       
  3559             if (aBatchCommit)
       
  3560                 {
       
  3561                 itemId = iDbHandler->AddSongWithNoTransactionL(aMedia, &aMessageArray);
       
  3562                 }
       
  3563             else
       
  3564                 {
       
  3565                 itemId = iDbHandler->AddSongL(aMedia, &aMessageArray);
       
  3566                 }
       
  3567             
       
  3568             MPXDbCommonUtil::AddItemChangedMessageL(aMessageArray, itemId, EMPXItemInserted,
       
  3569                 EMPXSong, KDBPluginUid);
       
  3570             }
       
  3571             break;
       
  3572 
       
  3573         default:
       
  3574             {
       
  3575             User::Leave(KErrNotSupported);
       
  3576             }
       
  3577         }
       
  3578 
       
  3579     return itemId;
       
  3580     }
       
  3581 
       
  3582 // ----------------------------------------------------------------------------
       
  3583 // Update the collection from a media
       
  3584 // ----------------------------------------------------------------------------
       
  3585 //
       
  3586 void CMPXDbPlugin::DoSetL(
       
  3587     const CMPXMedia& aMedia )
       
  3588     {
       
  3589     MPX_FUNC("CMPXDbPlugin::DoSetL");
       
  3590 
       
  3591     if (!aMedia.IsSupported(KMPXMediaGeneralType))
       
  3592         {
       
  3593         User::Leave(KErrArgument);
       
  3594         }
       
  3595 
       
  3596     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
  3597 
       
  3598     CMPXMessageArray* changeMsgArray = CMPXMessageArray::NewL();
       
  3599     CleanupStack::PushL(changeMsgArray);
       
  3600 
       
  3601     if (aMedia.ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) == EMPXGroup)
       
  3602         {
       
  3603         if (!aMedia.IsSupported(KMPXMediaArrayContents))
       
  3604             {
       
  3605             User::Leave(KErrArgument);
       
  3606             }
       
  3607 
       
  3608         CMPXMediaArray* array = aMedia.Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3609         User::LeaveIfNull( array );
       
  3610         TInt count( array->Count() );
       
  3611         for (TInt i = 0; i < count; ++i)
       
  3612             {
       
  3613             visibleChange = (CMPXDbActiveTask::TChangeVisibility)(visibleChange | DoSetItemL(*array->AtL(i), *changeMsgArray));
       
  3614             }
       
  3615         }
       
  3616     else
       
  3617         {
       
  3618         visibleChange = DoSetItemL(aMedia, *changeMsgArray);
       
  3619         }
       
  3620 
       
  3621     // Handle Change Events
       
  3622     if (visibleChange)
       
  3623         {
       
  3624         iActiveTask->SetVisibleChange(visibleChange);
       
  3625         DoHandleChangeL(changeMsgArray);
       
  3626         }
       
  3627     CleanupStack::PopAndDestroy(changeMsgArray);
       
  3628     }
       
  3629 
       
  3630 // ----------------------------------------------------------------------------
       
  3631 // Execute a task step for async set
       
  3632 // ----------------------------------------------------------------------------
       
  3633 //
       
  3634 TBool CMPXDbPlugin::DoSetAsyncL()
       
  3635     {
       
  3636     MPX_FUNC("CMPXDbPlugin::DoSetAsyncL");
       
  3637 
       
  3638     TBool done(EFalse);
       
  3639     CMPXMedia* task = iActiveTask->GetCommand().Value<CMPXMedia>(KMPXCommandColSetMedia);
       
  3640     User::LeaveIfNull( task );
       
  3641 
       
  3642     CMPXMessageArray& msgArray = iActiveTask->GetChangeMessages();
       
  3643     CMPXDbActiveTask::TChangeVisibility visibleChange(iActiveTask->GetVisibleChange());
       
  3644 
       
  3645     // Multiple steps can be in a transaction for faster response
       
  3646     if( !iDbHandler->InTransaction() )
       
  3647         {
       
  3648         iDbHandler->BeginTransactionL();
       
  3649         }
       
  3650 
       
  3651     if (!task->IsSupported(KMPXMediaGeneralType))
       
  3652         {
       
  3653         User::Leave(KErrArgument);
       
  3654         }
       
  3655 
       
  3656     if (task->ValueTObjectL<TMPXGeneralType>(KMPXMediaGeneralType) == EMPXGroup)
       
  3657         {
       
  3658         if (!task->IsSupported(KMPXMediaArrayContents))
       
  3659             {
       
  3660             User::Leave(KErrArgument);
       
  3661             }
       
  3662 
       
  3663         // Multiple items
       
  3664         CMPXMediaArray* array = task->Value<CMPXMediaArray>(KMPXMediaArrayContents);
       
  3665         User::LeaveIfNull( array );
       
  3666         TInt step = iActiveTask->GetStep();
       
  3667         visibleChange = (CMPXDbActiveTask::TChangeVisibility)(visibleChange | DoSetItemL(*array->AtL(step), msgArray));
       
  3668 
       
  3669         if (++step == array->Count())
       
  3670             {
       
  3671             done = ETrue;
       
  3672             }
       
  3673         }
       
  3674     else // Single item
       
  3675         {
       
  3676         visibleChange = DoSetItemL(*task, msgArray);
       
  3677         done = ETrue;
       
  3678         }
       
  3679     iActiveTask->SetVisibleChange(visibleChange);
       
  3680     return done;
       
  3681     }
       
  3682 
       
  3683 // ----------------------------------------------------------------------------
       
  3684 // Update the collection from a media
       
  3685 // ----------------------------------------------------------------------------
       
  3686 //
       
  3687 CMPXDbActiveTask::TChangeVisibility CMPXDbPlugin::DoSetItemL(
       
  3688     const CMPXMedia& aMedia,
       
  3689     CMPXMessageArray& aMessageArray )
       
  3690     {
       
  3691     MPX_FUNC("CMPXDbPlugin::DoSetItemL");
       
  3692 
       
  3693     TMPXGeneralCategory category = aMedia.ValueTObjectL<TMPXGeneralCategory>(KMPXMediaGeneralCategory);
       
  3694 
       
  3695     CMPXDbActiveTask::TChangeVisibility visibleChange(CMPXDbActiveTask::ENotVisibile);
       
  3696     switch (category)
       
  3697         {
       
  3698         case EMPXPlaylist:
       
  3699             {
       
  3700             if (aMedia.IsSupported(KMPXMediaArrayContents))
       
  3701                 {
       
  3702                 CMPXMessage* message = CMPXMedia::NewL();
       
  3703                 CleanupStack::PushL(message);
       
  3704 
       
  3705                 iDbHandler->UpdatePlaylistSongsL(aMedia, *message);
       
  3706 
       
  3707                 aMessageArray.AppendL(message); // ownership xfer
       
  3708                 CleanupStack::Pop(message);
       
  3709                 }
       
  3710             else
       
  3711                 {
       
  3712                 iDbHandler->UpdatePlaylistL(aMedia, aMessageArray);
       
  3713                 }
       
  3714 
       
  3715             visibleChange = CMPXDbActiveTask::ESingleVisible;
       
  3716             }
       
  3717             break;
       
  3718 #ifdef ABSTRACTAUDIOALBUM_INCLUDED
       
  3719         case EMPXAbstractAlbum:
       
  3720             {
       
  3721             visibleChange = iDbHandler->UpdateAbstractAlbumSongsL(aMedia, aMessageArray);
       
  3722             }
       
  3723             break;
       
  3724 #endif // ABSTRACTAUDIOALBUM_INCLUDED
       
  3725         case EMPXSong:
       
  3726             {
       
  3727             // a list of changed messages as a result of the song being updated
       
  3728             visibleChange = iDbHandler->UpdateSongL(aMedia, aMessageArray);
       
  3729             }
       
  3730             break;
       
  3731 
       
  3732         default:
       
  3733             {
       
  3734             User::Leave(KErrNotSupported);
       
  3735             }
       
  3736             break;
       
  3737         }
       
  3738     return visibleChange; // ownership xfer
       
  3739     }
       
  3740 
       
  3741 // ----------------------------------------------------------------------------
       
  3742 // Sets the drm properties for a list of medias
       
  3743 // ----------------------------------------------------------------------------
       
  3744 //
       
  3745 void CMPXDbPlugin::DoSetDrmForArrayL(
       
  3746     const CMPXMediaArray& mediaArray,
       
  3747     const TArray<TMPXAttribute>& aAttrs)
       
  3748     {
       
  3749     MPX_FUNC("CMPXDbPlugin::DoSetDrmForArrayL");
       
  3750 
       
  3751     TUint drmAttributes(0);
       
  3752 
       
  3753     // Compact the attribute set
       
  3754     //
       
  3755     TInt attrCount(aAttrs.Count());
       
  3756     for (TInt i = 0; i < attrCount; ++i)
       
  3757         {
       
  3758         if (aAttrs[i].ContentId() == KMPXMediaIdDrm)
       
  3759             {
       
  3760             drmAttributes |= aAttrs[i].AttributeId();
       
  3761             }
       
  3762         }
       
  3763 
       
  3764     // Fetch drm attributes for every item
       
  3765     //
       
  3766     if (drmAttributes)
       
  3767         {
       
  3768         TInt count(mediaArray.Count());
       
  3769         for (TInt i = 0; i < count; ++i)
       
  3770             {
       
  3771             if (mediaArray[i]->IsSupported(KMPXMediaGeneralUri))
       
  3772                 {
       
  3773                 DoSetMediaDrmL(*mediaArray[i], drmAttributes,
       
  3774                     mediaArray[i]->ValueText(KMPXMediaGeneralUri));
       
  3775                 }
       
  3776             }
       
  3777         }
       
  3778     }
       
  3779 
       
  3780 // ----------------------------------------------------------------------------
       
  3781 // Handle change events
       
  3782 // ----------------------------------------------------------------------------
       
  3783 //
       
  3784 void CMPXDbPlugin::HandleChangeL(
       
  3785     const CMPXMessage& aMessage)
       
  3786     {
       
  3787     MPX_FUNC("CMPXDbPlugin::HandleChange");
       
  3788 
       
  3789     // check if message is filled
       
  3790     if (aMessage.IsSupported(KMPXMessageGeneralId))
       
  3791         {
       
  3792 #if _DEBUG
       
  3793         PrintMessagesL(aMessage);
       
  3794 #endif // _DEBUG
       
  3795         if(iRefreshing)
       
  3796             {
       
  3797             if (aMessage.IsSupported(KMPXMessageArrayContents))
       
  3798                 {
       
  3799                 const CMPXMessageArray* messageArray = aMessage.Value<CMPXMessageArray>(KMPXMessageArrayContents);
       
  3800                 if(messageArray)
       
  3801                     {
       
  3802                     CMPXMessage& message = *((*messageArray)[0]);
       
  3803                     TMPXChangeEventType changeType( message.ValueTObjectL<TMPXChangeEventType>( KMPXMessageChangeEventType ) );
       
  3804                     TMPXGeneralCategory cat(message.ValueTObjectL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory));
       
  3805                     if(changeType == EMPXItemInserted && (cat == EMPXSong || cat == EMPXPlaylist || cat == EMPXPodcast))
       
  3806                         {
       
  3807                         iObs->HandleMessage(aMessage);
       
  3808                         }
       
  3809                     }
       
  3810                 }
       
  3811             else
       
  3812                 {
       
  3813                 TMPXChangeEventType changeType( aMessage.ValueTObjectL<TMPXChangeEventType>( KMPXMessageChangeEventType ) );
       
  3814                 TMPXGeneralCategory cat(aMessage.ValueTObjectL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory));
       
  3815                 if(changeType == EMPXItemInserted && (cat == EMPXSong || cat == EMPXPlaylist || cat == EMPXPodcast))
       
  3816                     {
       
  3817                     iObs->HandleMessage(aMessage);
       
  3818                     }
       
  3819                 }
       
  3820             }
       
  3821         else
       
  3822             {
       
  3823             if(!iMtpInUse)
       
  3824                 {
       
  3825                 iObs->HandleMessage(aMessage);
       
  3826                 }
       
  3827             }
       
  3828         }
       
  3829     }
       
  3830 
       
  3831 // ----------------------------------------------------------------------------
       
  3832 // Construct a CMPXMedia and call HandleChange
       
  3833 // ----------------------------------------------------------------------------
       
  3834 //
       
  3835 void CMPXDbPlugin::DoHandleChangeL(
       
  3836     CMPXMessageArray* aItemChangedMessages,
       
  3837     TMPXCommandId aCommandId )
       
  3838     {
       
  3839     MPX_FUNC("CMPXDbPlugin::DoHandleChangeL");
       
  3840 
       
  3841     if( (iActiveTask->GetVisibleChange() & CMPXDbActiveTask::EAllVisible)
       
  3842         && (aCommandId == KMPXCommandIdCollectionSet ||
       
  3843             aCommandId == KMPXCommandIdCollectionAdd ||
       
  3844             aCommandId == KMPXCommandIdCollectionRemove ||
       
  3845             aCommandId == KMPXCommandIdCollectionCompleteDelete ))
       
  3846         {
       
  3847         MPXDbCommonUtil::AddItemChangedMessageL(*aItemChangedMessages, EBrowseAll,
       
  3848                                                  EMPXItemModified, EMPXCollection, KDBPluginUid);
       
  3849         }
       
  3850     // group change messages and send to collection client context
       
  3851     //
       
  3852     CMPXMessage* message = CMPXMessage::NewL();
       
  3853     CleanupStack::PushL(message);
       
  3854 
       
  3855     message->SetTObjectValueL<TMPXMessageId>(KMPXMessageGeneralId, KMPXMessageIdItemChanged);
       
  3856     message->SetCObjectValueL(KMPXMessageArrayContents, aItemChangedMessages);
       
  3857     message->SetTObjectValueL<TInt>(KMPXMessageArrayCount, aItemChangedMessages->Count());
       
  3858 
       
  3859     HandleChangeL(*message);
       
  3860 
       
  3861     CleanupStack::PopAndDestroy(message);
       
  3862     }
       
  3863 
       
  3864 // ----------------------------------------------------------------------------
       
  3865 // Handle completion of operation
       
  3866 // ----------------------------------------------------------------------------
       
  3867 //
       
  3868 void CMPXDbPlugin::DoHandleOperationCompletedL(
       
  3869     TInt aErr)
       
  3870     {
       
  3871     MPX_FUNC("CMPXDbPlugin::DoHandleOperationCompletedL");
       
  3872 
       
  3873     // Broadcase change messages
       
  3874     //
       
  3875     if (iActiveTask->GetVisibleChange())
       
  3876         {
       
  3877         DoHandleChangeL(&iActiveTask->GetChangeMessages(), iActiveTask->GetTask() );
       
  3878         }
       
  3879 
       
  3880     // Callback to engine to signal completion
       
  3881     // NOTE: Collection server immediately completes the async message when
       
  3882     // Cancel is called, no need to callback to observer
       
  3883     if (aErr != KErrCancel)
       
  3884         {
       
  3885         if( iActiveTask->GetTask() == KMPXCommandIdCollectionAdd )
       
  3886             {
       
  3887             iObs->HandleCommandComplete( &iActiveTask->GetCommand(), aErr );
       
  3888             }
       
  3889         else
       
  3890             {
       
  3891             iObs->HandleCommandComplete(NULL, aErr);
       
  3892             }
       
  3893         }
       
  3894 
       
  3895     if( iDbHandler->InTransaction() )
       
  3896         {
       
  3897         // Commit if cancelled
       
  3898         TInt err(aErr);
       
  3899         if( err == KErrCancel )
       
  3900             {
       
  3901             err = KErrNone;
       
  3902             }
       
  3903         iDbHandler->EndTransactionL( err );
       
  3904         }
       
  3905     }
       
  3906 
       
  3907 // ----------------------------------------------------------------------------------------------------------
       
  3908 // Complete a delete operation
       
  3909 // ----------------------------------------------------------------------------------------------------------
       
  3910 //
       
  3911 void CMPXDbPlugin::DoHandleDeleteCompleteL(
       
  3912     CMPXCommand& aCmd)
       
  3913     {
       
  3914     MPX_FUNC("CMPXDbPlugin::DoHandleDeleteCompleteL");
       
  3915     iFirstDeleteStep = ETrue;
       
  3916     iSelections.Reset();
       
  3917     if ( iDbHandler->InTransaction() )
       
  3918         {
       
  3919         // if it can reach this point in a transaction, there's no error
       
  3920         iDbHandler->EndTransactionL( KErrNone );
       
  3921         }
       
  3922 
       
  3923     // Change messages
       
  3924     if (aCmd.IsSupported(KMPXCommandCollectionDeleteMsgArray))
       
  3925         {
       
  3926         CMPXMessageArray* msgs = aCmd.Value<CMPXMessageArray>(KMPXCommandCollectionDeleteMsgArray);
       
  3927         User::LeaveIfNull( msgs );
       
  3928         iActiveTask->SetVisibleChange(CMPXDbActiveTask::EAllVisible);
       
  3929         DoHandleChangeL(msgs, KMPXCommandIdCollectionCompleteDelete);
       
  3930         }
       
  3931     }
       
  3932 
       
  3933 // ----------------------------------------------------------------------------------------------------------
       
  3934 // Reorder a song in a playlist
       
  3935 // ----------------------------------------------------------------------------------------------------------
       
  3936 //
       
  3937 void CMPXDbPlugin::DoReorderPlaylistL(
       
  3938     const CMPXCommand& aCmd)
       
  3939     {
       
  3940     MPX_FUNC("CMPXDbPlugin::DoReorderPlaylistL");
       
  3941 
       
  3942     if (!aCmd.IsSupported(KMPXCommandReorderPlaylistId) ||
       
  3943         !aCmd.IsSupported(KMPXCommandReorderSongId) ||
       
  3944         !aCmd.IsSupported(KMPXCommandReorderOriginalOrdinal) ||
       
  3945         !aCmd.IsSupported(KMPXCommandReorderNewOrdinal))
       
  3946         {
       
  3947         User::Leave(KErrArgument);
       
  3948         }
       
  3949 
       
  3950     CMPXMessage* message = CMPXMedia::NewL();
       
  3951     CleanupStack::PushL(message);
       
  3952 
       
  3953     iDbHandler->ReorderPlaylistL(
       
  3954         aCmd.ValueTObjectL<TMPXItemId>(KMPXCommandReorderPlaylistId),
       
  3955         aCmd.ValueTObjectL<TMPXItemId>(KMPXCommandReorderSongId),
       
  3956         aCmd.ValueTObjectL<TUint>(KMPXCommandReorderOriginalOrdinal),
       
  3957         aCmd.ValueTObjectL<TUint>(KMPXCommandReorderNewOrdinal),
       
  3958         *message);
       
  3959 
       
  3960     HandleChangeL(*message);
       
  3961 
       
  3962     CleanupStack::PopAndDestroy(message);
       
  3963     }
       
  3964 
       
  3965 // ----------------------------------------------------------------------------------------------------------
       
  3966 // Get total songs and playlists count for a database
       
  3967 // ----------------------------------------------------------------------------------------------------------
       
  3968 //
       
  3969 void CMPXDbPlugin::DoGetCollectionCountL( const CMPXCommand& aCmd )
       
  3970     {
       
  3971     MPX_FUNC("CMPXDbPlugin::DoGetCollectionCountL");
       
  3972     if (!aCmd.IsSupported(KMPXCommandCollectionCountDrive) ||
       
  3973         !aCmd.IsSupported(KMPXCommandCollectionCountTable) )
       
  3974         {
       
  3975         User::Leave(KErrArgument);
       
  3976         }
       
  3977 
       
  3978     TInt count = 0;
       
  3979     TInt drive = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionCountDrive);
       
  3980     TInt table = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionCountTable);
       
  3981     switch(table)
       
  3982         {
       
  3983         case EMPXCollectionCountTrack:
       
  3984             count = (TInt)iDbHandler->GetMusicCountL(drive);
       
  3985             break;
       
  3986         case EMPXCollectionCountPlaylist:
       
  3987             count = (TInt)iDbHandler->GetPlaylistCountL(drive);
       
  3988             break;
       
  3989         case EMPXCollectionCountTotal:
       
  3990             count = (TInt)iDbHandler->GetTotalCountL(drive);
       
  3991             break;
       
  3992         default:
       
  3993             User::Leave(KErrArgument);
       
  3994         }
       
  3995     ((CMPXMedia&)aCmd).SetTObjectValueL<TInt>(KMPXCommandCollectionCountValue, count);
       
  3996     }
       
  3997 
       
  3998 // ----------------------------------------------------------------------------------------------------------
       
  3999 // Get URIs for all songs and file playlists in a database
       
  4000 // ----------------------------------------------------------------------------------------------------------
       
  4001 //
       
  4002 void CMPXDbPlugin::DoGetCollectionUriL( const CMPXCommand& aCmd )
       
  4003     {
       
  4004     MPX_FUNC("CMPXDbPlugin::DoGetCollectionCountL");
       
  4005     if (!aCmd.IsSupported(KMPXCommandCollectionURIDrive) ||
       
  4006         !aCmd.IsSupported(KMPXCommandCollectionURITable) ||
       
  4007         !aCmd.IsSupported(KMPXCommandCollectionURIFromID) ||
       
  4008         !aCmd.IsSupported(KMPXCommandCollectionURIRecords) )
       
  4009         {
       
  4010         User::Leave(KErrArgument);
       
  4011         }
       
  4012 
       
  4013     TInt drive = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionURIDrive);
       
  4014     TInt table = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionURITable);
       
  4015     TInt fromID = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionURIFromID);
       
  4016     TInt recnum = aCmd.ValueTObjectL<TInt>(KMPXCommandCollectionURIRecords);
       
  4017 
       
  4018     CDesCArray* uris = new(ELeave) CDesCArrayFlat(4);
       
  4019     CleanupStack::PushL(uris);
       
  4020     TInt lastID = 0;
       
  4021 
       
  4022     switch(table)
       
  4023         {
       
  4024         case EMPXCollectionURITrack:
       
  4025             iDbHandler->GetMusicUriArrayL(drive, fromID, recnum, *uris, lastID);
       
  4026             break;
       
  4027         case EMPXCollectionURIPlaylist:
       
  4028             iDbHandler->GetPlaylistUriArrayL(drive, fromID, recnum, *uris, lastID);
       
  4029             break;
       
  4030         default:
       
  4031             User::Leave(KErrArgument);
       
  4032         }
       
  4033 
       
  4034     ((CMPXMedia&)aCmd).SetNoNewLCObjectL(KMPXCommandCollectionURIList, uris);
       
  4035     ((CMPXMedia&)aCmd).SetTObjectValueL(KMPXCommandCollectionURILastID, lastID);
       
  4036     CleanupStack::PopAndDestroy(uris);
       
  4037     }
       
  4038 
       
  4039 
       
  4040 // ----------------------------------------------------------------------------------------------------------
       
  4041 // Perform one step of the incremental operation
       
  4042 // ----------------------------------------------------------------------------------------------------------
       
  4043 //
       
  4044 void CMPXDbPlugin::DoIncrementalOpenL( const CMPXCommand& aCmd )
       
  4045     {
       
  4046     MPX_DEBUG1("CMPXDbPlugin::DoIncrementalOpenL <--");
       
  4047 
       
  4048     TInt offset = aCmd.ValueTObjectL<TInt>( KMPXCollectionCommandIdIncOpenLOffset );
       
  4049     TInt numItems = aCmd.ValueTObjectL<TInt>( KMPXCollectionCommandIdIncOpenLNumItems );
       
  4050 
       
  4051     TReadDirection direction(EReadUnknown);
       
  4052     if( aCmd.IsSupported(KMPXCollectionCommandIdIncOpenLAscDsc) &&
       
  4053         aCmd.IsSupported(KMPXCollectionCommandIdIncOpenLKeyItem) )
       
  4054         {
       
  4055         direction = aCmd.ValueTObjectL<TReadDirection>(KMPXCollectionCommandIdIncOpenLAscDsc);
       
  4056         }
       
  4057 
       
  4058     CMPXCollectionPath* path =  aCmd.ValueCObjectL<CMPXCollectionPath>(KMPXCollectionCommandIdIncOpenLPath);
       
  4059     CleanupStack::PushL( path );
       
  4060     MPX_DEBUG_PATH( *path );
       
  4061 
       
  4062     // Switch on level and item selected
       
  4063     //
       
  4064     TInt levels( path->Levels() );
       
  4065     switch( levels )
       
  4066         {
       
  4067         case 3:  // levels of 3 top level is not stripped
       
  4068             {
       
  4069             switch( path->Id(1).iId2 )
       
  4070                 {
       
  4071                 case EBrowseAll:
       
  4072                     {
       
  4073                     CMPXMedia* results = CMPXMedia::NewL();
       
  4074                     CleanupStack::PushL( results );
       
  4075 
       
  4076                     TMPXOpenDataBlock block;
       
  4077                     block.iOffset = offset;
       
  4078                     block.iSize = numItems;
       
  4079 
       
  4080                     // Todo: this should come from the UI
       
  4081                     RArray<TMPXAttribute> attrs;
       
  4082                     CleanupClosePushL( attrs );
       
  4083                     attrs.AppendL(TMPXAttribute(KMPXMediaIdGeneral,
       
  4084                                    EMPXMediaGeneralId | EMPXMediaGeneralType | EMPXMediaGeneralCategory |
       
  4085                                    EMPXMediaGeneralTitle | EMPXMediaGeneralFlags | EMPXMediaGeneralUri));
       
  4086                     attrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4087                                         EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName ) );
       
  4088 
       
  4089                     // Array to read data from
       
  4090                     CMPXMediaArray* array = CMPXMediaArray::NewL();
       
  4091                     CleanupStack::PushL( array );
       
  4092 
       
  4093                     // Do we have to use offset or can we use asc/dsc
       
  4094                     //
       
  4095                     if( direction == EReadUnknown )
       
  4096                         {
       
  4097                         iDbHandler->GetSongsAtOffsetL( array, attrs.Array(), offset, numItems );
       
  4098                         }
       
  4099                     else
       
  4100                         {
       
  4101                         iDbHandler->GetSongsInBlockL( array, attrs.Array(),
       
  4102                                                       aCmd.ValueText( KMPXCollectionCommandIdIncOpenLKeyItem ),
       
  4103                                                       numItems,
       
  4104                                                       direction );
       
  4105                         }
       
  4106 
       
  4107                     TInt max( path->Count() );
       
  4108                     TInt count(0);
       
  4109                     TInt aryCount( array->Count() );
       
  4110                     // Update the collection path
       
  4111                     while( count<numItems && offset<max &&
       
  4112                            count<aryCount )
       
  4113                         {
       
  4114                         TMPXItemId id = array->AtL(count)->ValueTObjectL<TMPXItemId>( KMPXMediaGeneralId );
       
  4115                         path->Update( offset, id );
       
  4116 
       
  4117                         // Next items
       
  4118                         offset++;
       
  4119                         count++;
       
  4120                         }
       
  4121 
       
  4122                     // Setup the results
       
  4123                     //
       
  4124                     results->SetCObjectValueL(KMPXMediaArrayContents, array);
       
  4125                     results->SetTObjectValueL<TInt>(KMPXMediaArrayCount, array->Count());
       
  4126                     CleanupStack::PopAndDestroy( array );
       
  4127                     CleanupStack::PopAndDestroy( &attrs );
       
  4128 
       
  4129                     // Callback with results
       
  4130                     //
       
  4131                     results->SetTObjectValueL<TMPXOpenDataBlock>( KMPXCollectionOpenLResultRange, block );
       
  4132                     iObs->HandleOpen( results, path, KErrNone );
       
  4133                     CleanupStack::PopAndDestroy( results );
       
  4134                     break;
       
  4135                     }
       
  4136                 default:
       
  4137                     User::Leave(KErrNotSupported);
       
  4138                     break;
       
  4139                 }
       
  4140             break;
       
  4141             }
       
  4142         default:
       
  4143             {
       
  4144             User::Leave(KErrNotSupported);
       
  4145             break;
       
  4146             }
       
  4147 
       
  4148         }
       
  4149     CleanupStack::PopAndDestroy( path );
       
  4150 
       
  4151     MPX_DEBUG1("CMPXDbPlugin::DoIncrementalOpenL -->");
       
  4152     }
       
  4153 
       
  4154 // ----------------------------------------------------------------------------
       
  4155 // Maps a given browse type to a category ID.
       
  4156 // ----------------------------------------------------------------------------
       
  4157 //
       
  4158 TMPXGeneralCategory CMPXDbPlugin::CategoryForBrowseType(
       
  4159     TMCBrowseType aBrowseType)
       
  4160     {
       
  4161     MPX_FUNC("CMPXDbPlugin::CategoryForBrowseType");
       
  4162 
       
  4163     TMPXGeneralCategory cat(EMPXNoCategory);
       
  4164 
       
  4165     switch (aBrowseType)
       
  4166         {
       
  4167         case EBrowseAll:
       
  4168             {
       
  4169             cat = EMPXSong;
       
  4170             break;
       
  4171             }
       
  4172         case EBrowseArtist:
       
  4173             {
       
  4174             cat = EMPXArtist;
       
  4175             break;
       
  4176             }
       
  4177         case EBrowseAlbum:
       
  4178             {
       
  4179             cat = EMPXAlbum;
       
  4180             break;
       
  4181             }
       
  4182         case EBrowsePlaylist:
       
  4183             {
       
  4184             cat = EMPXPlaylist;
       
  4185             break;
       
  4186             }
       
  4187         case EBrowseGenre:
       
  4188             {
       
  4189             cat = EMPXGenre;
       
  4190             break;
       
  4191             }
       
  4192         case EBrowseComposer:
       
  4193             {
       
  4194             cat = EMPXComposer;
       
  4195             break;
       
  4196             }
       
  4197 #ifdef __ENABLE_PODCAST_IN_MUSIC_MENU
       
  4198         case EBrowsePodcasts:
       
  4199             {
       
  4200             cat = EMPXPodcast;
       
  4201             break;
       
  4202             }
       
  4203 #endif
       
  4204         default:
       
  4205             {
       
  4206             // do nothing
       
  4207             break;
       
  4208             }
       
  4209         }
       
  4210 
       
  4211     return cat;
       
  4212     }
       
  4213 
       
  4214 // ----------------------------------------------------------------------------
       
  4215 // Maps a given category ID to a browse type.
       
  4216 // ----------------------------------------------------------------------------
       
  4217 //
       
  4218 TMCBrowseType CMPXDbPlugin::BrowseTypeForCategory(
       
  4219     TMPXGeneralCategory aCategory)
       
  4220     {
       
  4221     MPX_FUNC("CMPXDbPlugin::BrowseTypeForCategory");
       
  4222 
       
  4223     TMCBrowseType browseType(EBrowseComposer);
       
  4224 
       
  4225     switch (aCategory)
       
  4226         {
       
  4227         case EMPXSong:
       
  4228             {
       
  4229             browseType = EBrowseAll;
       
  4230             break;
       
  4231             }
       
  4232         case EMPXArtist:
       
  4233             {
       
  4234             browseType = EBrowseArtist;
       
  4235             break;
       
  4236             }
       
  4237         case EMPXAlbum:
       
  4238             {
       
  4239             browseType = EBrowseAlbum;
       
  4240             break;
       
  4241             }
       
  4242         case EMPXPlaylist:
       
  4243             {
       
  4244             browseType = EBrowsePlaylist;
       
  4245             break;
       
  4246             }
       
  4247         case EMPXGenre:
       
  4248             {
       
  4249             browseType = EBrowseGenre;
       
  4250             break;
       
  4251             }
       
  4252         default:
       
  4253             {
       
  4254             // do nothing
       
  4255             break;
       
  4256             }
       
  4257         }
       
  4258 
       
  4259     return browseType;
       
  4260     }
       
  4261 
       
  4262 // ----------------------------------------------------------------------------
       
  4263 // Sets the type, category and title attributes in the specified media instance
       
  4264 // ----------------------------------------------------------------------------
       
  4265 //
       
  4266 void CMPXDbPlugin::SetMediaGeneralAttributesL(
       
  4267     CMPXMedia& aMedia,
       
  4268     TMPXGeneralType aType,
       
  4269     TMPXGeneralCategory aCategory,
       
  4270     const TDesC& aTitle)
       
  4271     {
       
  4272     aMedia.SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType, aType);
       
  4273     aMedia.SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory, aCategory);
       
  4274     aMedia.SetTextValueL(KMPXMediaGeneralTitle, aTitle);
       
  4275     }
       
  4276 
       
  4277 // ----------------------------------------------------------------------------
       
  4278 // Sets the type, category and title attributes in the specified media instance
       
  4279 // ----------------------------------------------------------------------------
       
  4280 //
       
  4281 void CMPXDbPlugin::SetMediaGeneralAttributesL(
       
  4282     CMPXMedia& aMedia,
       
  4283     TMPXGeneralType aType,
       
  4284     TMPXGeneralCategory aCategory,
       
  4285     TInt aId)
       
  4286     {
       
  4287     MPX_FUNC("CMPXDbPlugin::SetMediaGeneralAttributesL");
       
  4288 
       
  4289     HBufC* title = iDbHandler->GetNameMatchingIdL(aId);
       
  4290     CleanupStack::PushL(title);
       
  4291     SetMediaGeneralAttributesL(aMedia, aType, aCategory, *title);
       
  4292     CleanupStack::PopAndDestroy(title);
       
  4293     }
       
  4294 
       
  4295 // ----------------------------------------------------------------------------
       
  4296 // Set the attribute list according to current path
       
  4297 // ----------------------------------------------------------------------------
       
  4298 //
       
  4299 void CMPXDbPlugin::SetAttributesL(
       
  4300     const CMPXCollectionPath& aPath,
       
  4301     RArray<TMPXAttribute>& aAttrs,
       
  4302     RArray<TInt>& aSupportedIds )
       
  4303     {
       
  4304     aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral,
       
  4305         EMPXMediaGeneralId | EMPXMediaGeneralType | EMPXMediaGeneralCategory |
       
  4306         EMPXMediaGeneralTitle | EMPXMediaGeneralFlags | EMPXMediaGeneralUri) );
       
  4307 
       
  4308     aSupportedIds.AppendL(KMPXMediaIdContainer);
       
  4309     aSupportedIds.AppendL(KMPXMediaIdGeneral);
       
  4310 
       
  4311     TInt levels(aPath.Levels());
       
  4312     if ( 2 == levels )
       
  4313         {
       
  4314         // check the browse type
       
  4315         switch ( aPath.Id(1).iId2 )
       
  4316             {
       
  4317             case EBrowseAll:
       
  4318                 {
       
  4319                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4320                     EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName ) );
       
  4321                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4322                 break;
       
  4323                 }
       
  4324             case EBrowseArtist:
       
  4325                 {
       
  4326                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralCount) );
       
  4327                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4328                                     EMPXMediaMusicAlbumArtFileName ) );
       
  4329                 break;
       
  4330                 }
       
  4331             case EBrowseAlbum:
       
  4332                 {
       
  4333                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4334                     EMPXMediaMusicArtist | EMPXMediaMusicAlbum | EMPXMediaMusicAlbumArtFileName ) );
       
  4335                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4336                 break;
       
  4337                 }
       
  4338             case EBrowsePlaylist:
       
  4339                 {
       
  4340                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral,
       
  4341                     EMPXMediaGeneralCount | EMPXMediaGeneralDuration ) );
       
  4342                 break;
       
  4343                 }
       
  4344             case EBrowseGenre:
       
  4345                 {
       
  4346                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralCount) );
       
  4347                 break;
       
  4348                 }
       
  4349             case EBrowseComposer:
       
  4350                 {
       
  4351                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralCount) );
       
  4352                 break;
       
  4353                 }
       
  4354             default:
       
  4355                 {
       
  4356                 User::Leave(KErrArgument);
       
  4357                 }
       
  4358             }
       
  4359         }
       
  4360     else if ( 3 == levels )
       
  4361         {
       
  4362         // check the browse type
       
  4363         switch ( aPath.Id(1).iId2 )
       
  4364             {
       
  4365             case EBrowseArtist:
       
  4366                 {
       
  4367                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdGeneral, EMPXMediaGeneralCount) );
       
  4368                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic, EMPXMediaMusicAlbumArtFileName ) );
       
  4369                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4370                 break;
       
  4371                 }
       
  4372             case EBrowseAlbum:
       
  4373                 {
       
  4374 
       
  4375                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4376                     EMPXMediaMusicArtist | EMPXMediaMusicAlbum | EMPXMediaMusicAlbumArtFileName ) );
       
  4377                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4378                 break;
       
  4379                 }
       
  4380             case EBrowsePlaylist:
       
  4381             case EBrowseGenre:
       
  4382             case EBrowseComposer:
       
  4383                 {
       
  4384                 aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4385 //                    EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName ) );                    
       
  4386                 //added ganes
       
  4387                     EMPXMediaMusicArtist | EMPXMediaMusicAlbumArtFileName | EMPXMediaMusicAlbum) );                    
       
  4388                 aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4389                 break;
       
  4390                 }
       
  4391             }
       
  4392         }
       
  4393     else if ( (4 == levels) && (aPath.Id(1).iId2 == EBrowseArtist) )
       
  4394         {
       
  4395         aAttrs.AppendL( TMPXAttribute(KMPXMediaIdMusic,
       
  4396             EMPXMediaMusicArtist | EMPXMediaMusicAlbum | EMPXMediaMusicAlbumArtFileName ) );
       
  4397         aSupportedIds.AppendL( KMPXMediaIdMusic );
       
  4398         }
       
  4399     }
       
  4400 
       
  4401 #ifdef _DEBUG
       
  4402 // ----------------------------------------------------------------------------
       
  4403 // Print change events
       
  4404 // ----------------------------------------------------------------------------
       
  4405 //
       
  4406 void CMPXDbPlugin::PrintMessagesL(
       
  4407     const CMPXMessage& aMessage)
       
  4408     {
       
  4409     MPX_FUNC("CMPXDbPlugin::PrintMessages");
       
  4410 
       
  4411     if (aMessage.IsSupported(KMPXMessageArrayContents))
       
  4412         {
       
  4413         const CMPXMessageArray* messageArray =
       
  4414             aMessage.Value<CMPXMessageArray>(KMPXMessageArrayContents);
       
  4415         if( !messageArray )
       
  4416             {
       
  4417             User::Leave( KErrNoMemory );
       
  4418             }
       
  4419 
       
  4420         TInt count(messageArray->Count());
       
  4421         MPX_DEBUG2("%d messages:", count);
       
  4422 
       
  4423         for (TInt i = 0; i < count; ++i)
       
  4424             {
       
  4425             PrintMessage(*((*messageArray)[i]));
       
  4426             }
       
  4427         }
       
  4428     else
       
  4429         {
       
  4430         PrintMessage(aMessage);
       
  4431         }
       
  4432     }
       
  4433 
       
  4434 // ----------------------------------------------------------------------------
       
  4435 // Print one change event
       
  4436 // ----------------------------------------------------------------------------
       
  4437 //
       
  4438 void CMPXDbPlugin::PrintMessage(
       
  4439     const CMPXMessage& aMessage)
       
  4440     {
       
  4441     MPX_FUNC("CMPXDbPlugin::PrintMessage");
       
  4442 
       
  4443     if (aMessage.IsSupported(KMPXMessageGeneralId))
       
  4444         {
       
  4445         TMPXItemId id = aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageGeneralId);
       
  4446         MPX_DEBUG3("    message id[0x%x, 0x%x]", id.iId1, id.iId2);
       
  4447         }
       
  4448 
       
  4449     if (aMessage.IsSupported(KMPXMessageCollectionId))
       
  4450         {
       
  4451         TUid uid = aMessage.ValueTObjectL<TUid>(KMPXMessageCollectionId);
       
  4452         MPX_DEBUG2("    uid [0x%x]", uid.iUid);
       
  4453         }
       
  4454 
       
  4455     if (aMessage.IsSupported(KMPXMessageChangeEventType))
       
  4456         {
       
  4457         MPX_DEBUG2("    change event type [%d]",
       
  4458             aMessage.ValueTObjectL<TMPXChangeEventType>(KMPXMessageChangeEventType));
       
  4459         }
       
  4460 
       
  4461     if (aMessage.IsSupported(KMPXMessageMediaGeneralCategory))
       
  4462         {
       
  4463         MPX_DEBUG2("    category [%d]",
       
  4464             aMessage.ValueTObjectL<TMPXGeneralCategory>(KMPXMessageMediaGeneralCategory));
       
  4465         }
       
  4466 
       
  4467     if (aMessage.IsSupported(KMPXMessageMediaGeneralId))
       
  4468         {
       
  4469         TMPXItemId id = aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageMediaGeneralId);
       
  4470         MPX_DEBUG3("    media id[0x%x, 0x%x]", id.iId1, id.iId2);
       
  4471         }
       
  4472 
       
  4473     if (aMessage.IsSupported(KMPXMessageMediaDeprecatedId))
       
  4474         {
       
  4475         TMPXItemId id = aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageMediaDeprecatedId);
       
  4476         MPX_DEBUG3("    deprecated id [0x%x, 0x%x]", id.iId1, id.iId2);
       
  4477         }
       
  4478     }
       
  4479 
       
  4480 #endif// _DEBUG
       
  4481 
       
  4482 // End of file