mmappcomponents/harvester/filehandler/src/mpxharvesterfilehandlerimp.cpp
changeset 0 a2952bb97e68
child 9 bee149131e4b
child 25 d881023c13eb
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     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:  Handles all file related activities
       
    15 *  Version     : %version: da1mmcf#72.1.14.2.4.1.4.1.2 % << Don't touch! Updated by Synergy at check-out.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include <e32base.h>
       
    21 #include <f32file.h>
       
    22 #include <centralrepository.h>
       
    23 #ifdef RD_MULTIPLE_DRIVE
       
    24 #include <pathinfo.h>
       
    25 #include <driveinfo.h>
       
    26 #endif //RD_MULTIPLE_DRIVE
       
    27 
       
    28 #include <mpxlog.h>
       
    29 #include <mpxharvestercommon.h>
       
    30 #include <mpxmedia.h>
       
    31 #include <mpxmediaarray.h>
       
    32 #include <mpxcollectiontype.h>
       
    33 #include <mpxcollectionutility.h>
       
    34 #include <mpxcollectionpath.h>
       
    35 #include <mpxmediageneraldefs.h>
       
    36 #include <mpxmediacontainerdefs.h>
       
    37 
       
    38 #include <mpxdrmmediautility.h>
       
    39 #include <mpxmediadrmdefs.h>
       
    40 #include <mpxcollectionplugin.hrh>
       
    41 #include <mpxcollectionmediator.h>
       
    42 
       
    43 #include <mpxcommandgeneraldefs.h>
       
    44 #include <mpxcollectioncommanddefs.h>
       
    45 #include <DRMNotifier.h>
       
    46 #include <DRMEventAddRemove.h>
       
    47 #include <Oma2Agent.h>
       
    48 #include <caf/caferr.h>
       
    49 #include <caf/content.h>
       
    50 #include <caf/data.h>
       
    51 #include <UsbWatcherInternalPSKeys.h>
       
    52 #include <usbpersonalityids.h>
       
    53 
       
    54 #include "mpxharvesterfilehandlerimp.h"
       
    55 #include "mpxfolderscanner.h"
       
    56 #include "mpxdbsynchronizer.h"
       
    57 #include "mpxfoldermonitor.h"
       
    58 #include "mpxmetadatascanner.h"
       
    59 #include "mpxplaylistscanner.h"
       
    60 #include "mpxharvesterdbmanager.h"
       
    61 #include "mpxharvesterdbtable.h"
       
    62 #include "mpxharvesterdbitem.h"
       
    63 #include "mpxfhcommon.h"
       
    64 #include "mpxbrokenlinkcleanup.h"
       
    65 
       
    66 // ============ CONSTANTS ==========
       
    67 _LIT( KDefaultScanPath, "C:\\DATA\\|E:\\" );
       
    68 _LIT( KDefaultBlockPath, "\\SYS\\|\\PRIVATE\\|\\SYSTEM\\|\\CITIES\\");
       
    69 _LIT( KDefaultContainers, ".odf|.dcf|.asf|.m4a|.mp4" );
       
    70 _LIT( KDefaultAutoScanFolder, "C:\\data\\sounds\\digital\\|E:\\sounds\\digital\\");
       
    71 const TUid KCRUIDHarvesterFeatures  = { 0x101FFCD2 };
       
    72 const TUid KMusicPlayerUid = {0x102072C3};
       
    73 const TInt KHarvesterScanPathKey = 1;
       
    74 const TInt KHarvesterBlockPathKey = 2;
       
    75 const TInt KHarvesterContainerKey = 3;
       
    76 const TInt KAutoScanDirectoryKey = 4;
       
    77 const TInt KDisablePodcasting = 5;
       
    78 const TInt KAutoScanDelay = 10000000;  // 10 second delay for rights to arrive
       
    79 const TInt KAutoScanAfter = 10000000;
       
    80 
       
    81 // ==========LOCAL FUNCTIONS ========
       
    82 static void CleanupArray( TAny* item )
       
    83     {
       
    84     ((RPointerArray<CMPXHarvesterDbItem>*) item )->ResetAndDestroy();
       
    85     }
       
    86 
       
    87 // ======== MEMBER FUNCTIONS ========
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // C++ Constructor
       
    91 // ---------------------------------------------------------------------------
       
    92 //
       
    93 CMPXHarvesterFileHandlerImp::CMPXHarvesterFileHandlerImp( RFs& aFs ) :
       
    94         iFs( aFs ),
       
    95         iSynchronizing(EFalse),
       
    96         iDisablePodcasting(EFalse)
       
    97     {
       
    98     }
       
    99 
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // 2nd Phase Constructor
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 void CMPXHarvesterFileHandlerImp::ConstructL()
       
   106     {
       
   107     // Folder monitoring related,
       
   108     //
       
   109     User::LeaveIfError( iAppArc.Connect() );
       
   110     iFolderScanner = CMPXFolderScanner::NewL( *this, *this, iFs );
       
   111     iMetadataScanner = CMPXMetadataScanner::NewL( iFs,
       
   112                                                   iAppArc,
       
   113                                                   iSupportedTypes,
       
   114                                                   *this, *this );
       
   115     iPlaylistScanner = CMPXPlaylistScanner::NewL( *this,
       
   116                                                   *this,
       
   117                                                   iSupportedTypes );
       
   118 
       
   119     iBrokenLink = CMPXBrokenLinkCleanup::NewL( *this, *this );
       
   120     
       
   121     // Database related
       
   122     //
       
   123     iDBManager = CMPXHarvesterDatabaseManager::NewL( iFs );
       
   124     
       
   125     // List of watchers for different drives
       
   126     //
       
   127 #ifdef RD_MULTIPLE_DRIVE
       
   128     TDriveList driveList;
       
   129     TInt driveCount(0);
       
   130     User::LeaveIfError( DriveInfo::GetUserVisibleDrives(
       
   131            iFs, driveList, driveCount ) );
       
   132 
       
   133     for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
       
   134         {
       
   135         if ( driveList[driveNum] && (!iDBManager->IsRemoteDrive(static_cast<TDriveNumber>(driveNum))))
       
   136             {
       
   137             CMPXDiskSpaceWatcher* dw = CMPXDiskSpaceWatcher::NewL(
       
   138                     iFs, static_cast<TDriveNumber>(driveNum), *this );
       
   139             CleanupStack::PushL( dw );
       
   140             iDiskMonitors.AppendL( dw );
       
   141             CleanupStack::Pop( dw );
       
   142             }
       
   143         }
       
   144 #else
       
   145     CMPXDiskSpaceWatcher* dw_e = CMPXDiskSpaceWatcher::NewL( iFs, EDriveE, *this );
       
   146     CleanupStack::PushL( dw_e );
       
   147     iDiskMonitors.AppendL( dw_e );
       
   148     CleanupStack::Pop( dw_e );
       
   149     CMPXDiskSpaceWatcher* dw_c = CMPXDiskSpaceWatcher::NewL( iFs, EDriveC, *this );
       
   150     CleanupStack::PushL( dw_c );
       
   151     iDiskMonitors.AppendL( dw_c );
       
   152     CleanupStack::Pop( dw_c );
       
   153 #endif // RD_MULTIPLE_DRIVE
       
   154    
       
   155 
       
   156     TInt openerr = iDBManager->OpenAllDatabasesL();
       
   157     
       
   158     // Temporary collection utility
       
   159     //
       
   160     MMPXCollectionUtility* colUtil =
       
   161                            MMPXCollectionUtility::NewL( NULL, KMcModeDefault );
       
   162     CleanupStack::PushL( colUtil );
       
   163 
       
   164     // Get the collection UIDs
       
   165     RArray<TUid> ary;
       
   166     CleanupClosePushL( ary );
       
   167     ary.AppendL( TUid::Uid(EMPXCollectionPluginMusic) );
       
   168     iMusicCollectionId = colUtil->CollectionIDL( ary.Array() );
       
   169     ary.Reset();
       
   170     ary.AppendL( TUid::Uid(EMPXCollectionPluginPodCast) );
       
   171     iPodcastCollectionId = colUtil->CollectionIDL( ary.Array() );
       
   172     CleanupStack::PopAndDestroy( &ary );
       
   173 
       
   174     // If harvester db was corrupted, mark podcast and music db as corrupt
       
   175     if( openerr == KErrCorrupt )
       
   176         {
       
   177         colUtil->Collection().CommandL(EMcCmdDbCorrupted, iMusicCollectionId.iUid );
       
   178         colUtil->Collection().CommandL(EMcCmdDbCorrupted, iPodcastCollectionId.iUid );
       
   179         }
       
   180 
       
   181     // Get the list of supported types from the collection
       
   182     //
       
   183     colUtil->Collection().GetSupportedTypesL( iSupportedTypes );
       
   184     CleanupStack::Pop( colUtil );
       
   185     colUtil->Close();
       
   186 
       
   187     // Get the scan drives from cenrep.
       
   188     //
       
   189     ParseScanPathL();
       
   190 
       
   191     // Get the list of container types
       
   192     iContainerTypes = new(ELeave) CDesCArrayFlat(2);  // granularity
       
   193     ParseContainersL();
       
   194 
       
   195     // Get the list of automatic scanned folders
       
   196     ParseAutoScanL();
       
   197     iIdle = CPeriodic::NewL( CActive::EPriorityLow );
       
   198 
       
   199     // Get the podcasting enabled / disabled flag
       
   200     //
       
   201     CRepository* cenrep(NULL);
       
   202     TRAPD( err, cenrep = CRepository::NewL( KCRUIDHarvesterFeatures ) );
       
   203     if( err == KErrNone )
       
   204         {
       
   205         cenrep->Get( KDisablePodcasting, iDisablePodcasting );
       
   206         delete cenrep;
       
   207         }
       
   208     else
       
   209         {
       
   210         iDisablePodcasting = EFalse;
       
   211         }
       
   212 
       
   213     // Create the database synchronizer
       
   214     iDbSynchronizer = CMPXDbSynchronizer::NewL(*this,*iDBManager,iMusicCollectionId,
       
   215                                                iPodcastCollectionId,iFs, iDisablePodcasting);
       
   216 
       
   217 #ifdef RD_MULTIPLE_DRIVE
       
   218     // Use default MMC drive as the Removable drive
       
   219     User::LeaveIfError( DriveInfo::GetDefaultDrive(
       
   220         DriveInfo::EDefaultRemovableMassStorage,
       
   221         iRemovedDrive ) );
       
   222 #endif
       
   223 
       
   224     // Create DRM Notifier and register for AddRemove event
       
   225     iDrmNotifier = CDRMNotifier::NewL();
       
   226     iDrmNotifier->RegisterEventObserverL( *this, KEventAddRemove );
       
   227     }
       
   228 
       
   229 // ---------------------------------------------------------------------------
       
   230 // Two-Phased Constructor
       
   231 // ---------------------------------------------------------------------------
       
   232 //
       
   233 CMPXHarvesterFileHandlerImp* CMPXHarvesterFileHandlerImp::NewL( RFs& aFs )
       
   234     {
       
   235     CMPXHarvesterFileHandlerImp* self =
       
   236                                   new( ELeave ) CMPXHarvesterFileHandlerImp(aFs);
       
   237     CleanupStack::PushL( self );
       
   238     self->ConstructL();
       
   239     CleanupStack::Pop( self );
       
   240     return self;
       
   241     }
       
   242 
       
   243 // ---------------------------------------------------------------------------
       
   244 // Destructor
       
   245 // ---------------------------------------------------------------------------
       
   246 //
       
   247 CMPXHarvesterFileHandlerImp::~CMPXHarvesterFileHandlerImp()
       
   248     {
       
   249     MPX_DEBUG1("~CMPXHarvesterFileHandlerImp <---");
       
   250     delete iDbSynchronizer;
       
   251     delete iFolderScanner;
       
   252     delete iMetadataScanner;
       
   253     delete iPlaylistScanner;
       
   254     delete iBrokenLink;
       
   255 
       
   256     iDiskMonitors.ResetAndDestroy();
       
   257     iDiskMonitors.Close();
       
   258 
       
   259     iFolderMonitors.ResetAndDestroy();
       
   260     iFolderMonitors.Close();
       
   261 
       
   262 
       
   263     iSupportedTypes.ResetAndDestroy();
       
   264     iSupportedTypes.Close();
       
   265 
       
   266     if( iContainerTypes )
       
   267         {
       
   268         iContainerTypes->Reset();
       
   269         }
       
   270     delete iContainerTypes;
       
   271 
       
   272     iFilteredDrivesToScan.Reset();
       
   273     iFilteredDrivesToScan.Close();
       
   274     iDrivesToScan.Reset();
       
   275     iDrivesToScan.Close();
       
   276     iPathsToBlock.Reset();
       
   277     iPathsToBlock.Close();
       
   278 
       
   279     // Cleans up the scanning tables and arrays
       
   280     Reset();
       
   281 
       
   282     delete iDBManager;
       
   283 
       
   284     if( iCollectionUtil )
       
   285         {
       
   286         iCollectionUtil->Close();
       
   287         }
       
   288 
       
   289     iAppArc.Close();
       
   290 
       
   291     iAutoScanPaths.Reset();
       
   292     iAutoScanPaths.Close();
       
   293     delete iIdle;
       
   294     
       
   295     if(iDrmNotifier)
       
   296         {
       
   297         TRAP_IGNORE( iDrmNotifier->UnRegisterEventObserverL( *this, KEventAddRemove ) );
       
   298         delete iDrmNotifier;
       
   299         }
       
   300     MPX_DEBUG1("~CMPXHarvesterFileHandlerImp --->");
       
   301     }
       
   302 
       
   303 // ---------------------------------------------------------------------------
       
   304 // Scans all drives in the list of interested drives
       
   305 // ---------------------------------------------------------------------------
       
   306 //
       
   307 void CMPXHarvesterFileHandlerImp::ScanL()
       
   308     {
       
   309     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::ScanL <---");
       
   310 
       
   311     // Reset all previous states
       
   312     CancelScan();
       
   313     Reset();
       
   314 
       
   315     // Construct the collection utility
       
   316     if( iCollectionUtil )
       
   317         {
       
   318         iCollectionUtil->Close();
       
   319         iCollectionUtil = NULL;
       
   320         }
       
   321     iCollectionUtil = MMPXCollectionUtility::NewL( NULL, KMusicPlayerUid );
       
   322     
       
   323     // cenrep key need to be checked whether USB cable is connected in MTP/Combined Mode
       
   324     // to prevent refresh
       
   325     TInt usbStatus;
       
   326     RProperty::Get(KPSUidUsbWatcher, KUsbWatcherSelectedPersonality, usbStatus);
       
   327        
       
   328     if ((usbStatus == KUsbPersonalityIdMTP) || (usbStatus == KUsbPersonalityIdPCSuiteMTP))
       
   329         {
       
   330         MPX_DEBUG1("USB is active, Leave with KErrLocked");
       
   331         // need to call back even if it leaves here
       
   332         iCollectionUtil->Collection().NotifyL( EMcMsgRefreshEnd, KErrLocked );
       
   333         //User::Leave(KErrLocked);
       
   334         return;
       
   335         }
       
   336    
       
   337     iCollectionUtil->Collection().NotifyL( EMcMsgRefreshStart, KErrNone );
       
   338 
       
   339     // Reopen databases
       
   340     iDBManager->OpenAllDatabasesL();
       
   341 
       
   342     // Begin transaction on databases
       
   343     iDBManager->BeginL();
       
   344     
       
   345     //Remove out of disk space drives from scanned drives list
       
   346     iFilteredDrivesToScan.Reset();
       
   347     CopyArrayL(iDrivesToScan.Array(),iFilteredDrivesToScan);
       
   348 
       
   349     iOutOfDisk = EFalse;
       
   350     TInt driveCount (iDiskMonitors.Count());
       
   351     TBool outOfDisk(EFalse);
       
   352     for( TInt driveIndex = 0; driveIndex < driveCount; ++driveIndex )
       
   353         {
       
   354         //Check if the current drive is low on disk
       
   355         outOfDisk = iDiskMonitors[driveIndex]->IsLowOnDisk();
       
   356         iDiskMonitors[driveIndex]->StartL();
       
   357 
       
   358         if(outOfDisk)
       
   359             {
       
   360             TInt count( iFilteredDrivesToScan.Count() );
       
   361             TInt index(0);
       
   362             TInt currentDriveNumber = iDiskMonitors[driveIndex]->CurrentDrive();
       
   363             while(index < count)
       
   364                 {
       
   365                 // Remove current drive from the scanned drives list
       
   366                 TParse fileNameParser;
       
   367                 User::LeaveIfError(fileNameParser.Set(iFilteredDrivesToScan[index],NULL,NULL));
       
   368                 TFileName driveName(fileNameParser.Drive());
       
   369                 TInt driveNumber = TDriveUnit( driveName );
       
   370                 if (currentDriveNumber == driveNumber)
       
   371                     {
       
   372                     iFilteredDrivesToScan.Remove(index);
       
   373                     count--;
       
   374                     }
       
   375                 else
       
   376                     {
       
   377                     index++;
       
   378                     }
       
   379                 }
       
   380             TRAP_IGNORE(iDBManager->RemoveDatabaseL(static_cast<TDriveNumber>(currentDriveNumber)));
       
   381             }
       
   382         }
       
   383 
       
   384     iSynchronizing = CheckDbInSyncL();
       
   385 
       
   386     if(!iSynchronizing)
       
   387         {
       
   388         // Start the scanning process
       
   389         iRefreshCount++;
       
   390         iFolderScanner->ScanL( iFilteredDrivesToScan );
       
   391         iMetadataScanner->Reset();
       
   392         iBrokenLink->Reset();
       
   393         iPlaylistScanner->Reset();
       
   394         iIdle->Cancel();
       
   395 
       
   396         // Keep a count of how many we added to synchronize the number
       
   397         iAddedCount = 0;
       
   398         iRefreshing = ETrue;
       
   399         }
       
   400 
       
   401     if (iFilteredDrivesToScan.Count() == 0 )
       
   402         {
       
   403         iOutOfDisk = ETrue;
       
   404         MPX_DEBUG1("CMPXHarvesterFileHandlerImp::ScanL -- cancelling scan");
       
   405         // Cancel the scan in this case, will goto HandleScanStateCompleteL()
       
   406         CancelScan();
       
   407         }
       
   408     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::ScanL --->");
       
   409     }
       
   410 
       
   411 // ---------------------------------------------------------------------------
       
   412 // Cancels Scanning
       
   413 // ---------------------------------------------------------------------------
       
   414 //
       
   415 void CMPXHarvesterFileHandlerImp::CancelScan()
       
   416     {
       
   417     iDbSynchronizer->Cancel();
       
   418     iFolderScanner->Cancel();
       
   419     iBrokenLink->Cancel();
       
   420     iMetadataScanner->Stop();
       
   421     iPlaylistScanner->Cancel();
       
   422     }
       
   423 
       
   424 // ---------------------------------------------------------------------------
       
   425 // Handles a system event
       
   426 // ---------------------------------------------------------------------------
       
   427 //
       
   428 void CMPXHarvesterFileHandlerImp::HandleSystemEventL( TSystemEvent aEvent,
       
   429                                                       TInt aData )
       
   430     {
       
   431     MPX_DEBUG2("CMPXHarvesterFileHandlerImp::HandleSystemEventL %i", aEvent);
       
   432     // How to handle each event
       
   433     //
       
   434     // 1: Format and eject, we stop scanning and close only the mmc db
       
   435     // 2: Format end and disk insert we reopen db and scan for new files
       
   436     // 3: USB start we stop scan and close all db
       
   437     // 4: USB end we re-open all db and scan for new files
       
   438     // 5: MTP start we stop monitoring for new files (no dismount)
       
   439     // 6: MTP end we re-open all db, files added already, restart monitor
       
   440     //
       
   441 #ifdef RD_MULTIPLE_DRIVE
       
   442     // Get all visible drives
       
   443     TDriveList driveList;
       
   444     TInt driveCount(0);
       
   445     TPtrC drivePresent(_L("present"));
       
   446     TPtrC driveNotPresent(_L("not present"));
       
   447     TPtrC driveInUse(_L("in use"));
       
   448     TPtrC driveAvailable(_L("available"));
       
   449     TPtrC driveFormatted(_L("formatted"));
       
   450     TPtrC driveNotFormatted(_L("not formatted"));
       
   451     User::LeaveIfError( DriveInfo::GetUserVisibleDrives(
       
   452            iFs, driveList, driveCount ) );
       
   453     MPX_DEBUG2 ("CMPXHarvesterFileHandlerImp::HandleSystemEventL - driveCount = %d", driveCount);
       
   454 
       
   455     for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
       
   456         {
       
   457         if (driveList[driveNum])
       
   458             {
       
   459             // Get the drive status
       
   460             TUint driveStatus(0);
       
   461             User::LeaveIfError( DriveInfo::GetDriveStatus(
       
   462                 iFs, driveNum, driveStatus ) );
       
   463             MPX_DEBUG3 ("CMPXHarvesterFileHandlerImp::HandleSystemEventL - drive %d status=0x%x", driveNum, driveStatus);
       
   464             TChar driveChar;
       
   465             User::LeaveIfError(
       
   466                 iFs.DriveToChar( driveNum, driveChar ) );
       
   467             MPX_DEBUG5 ("CMPXHarvesterFileHandlerImp::HandleSystemEventL - drive %c: is %S, %S and %S",
       
   468                 driveChar,
       
   469                 (driveStatus&DriveInfo::EDrivePresent)?&drivePresent:&driveNotPresent,
       
   470                 (driveStatus&DriveInfo::EDriveInUse)?&driveInUse:&driveAvailable,
       
   471                 (driveStatus&DriveInfo::EDriveFormatted)?&driveFormatted:&driveNotFormatted);
       
   472             }
       
   473         }
       
   474 #endif //RD_MULTIPLE_DRIVE
       
   475     switch( aEvent )
       
   476         {
       
   477         case EFormatStartEvent:
       
   478             {
       
   479             MPX_DEBUG1("Disk Format start event");
       
   480             CancelScan();
       
   481             iDBManager->CloseDatabase( (TDriveNumber) aData );
       
   482             break;
       
   483             }
       
   484         case EDiskRemovedEvent:
       
   485             {
       
   486             MPX_DEBUG1("Disk Removed event");
       
   487             iIdle->Cancel();
       
   488             CancelScan();
       
   489 #ifdef RD_MULTIPLE_DRIVE
       
   490             for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
       
   491                 {
       
   492                 if (driveList[driveNum] && (!iDBManager->IsRemoteDrive(static_cast<TDriveNumber>(driveNum))))
       
   493                     {
       
   494                     TUint driveStatus(0);
       
   495                     User::LeaveIfError( DriveInfo::GetDriveStatus(
       
   496                         iFs, driveNum, driveStatus ) );
       
   497                     if (!(driveStatus & DriveInfo::EDrivePresent ))
       
   498                         {
       
   499                         // Close database for non-present drive
       
   500                         iDBManager->CloseDatabase( (TDriveNumber) driveNum );
       
   501                         // Save the drive
       
   502                         iRemovedDrive = driveNum;
       
   503                         break;
       
   504                         }
       
   505                     }
       
   506                 }
       
   507 #else
       
   508             iDBManager->CloseDatabase( (TDriveNumber) aData );
       
   509 #endif // RD_MULTIPLE_DRIVE
       
   510             break;
       
   511             }
       
   512         case EFormatEndEvent:
       
   513             {
       
   514             MPX_DEBUG1("Disk Format end event");
       
   515             CancelScan();
       
   516             iDBManager->OpenDatabaseL( (TDriveNumber) aData );
       
   517             break;
       
   518             }
       
   519         case EDiskInsertedEvent:
       
   520             {
       
   521             MPX_DEBUG1("Disk Insert event");
       
   522             CancelScan();
       
   523 #ifdef RD_MULTIPLE_DRIVE
       
   524             iDBManager->OpenDatabaseL( (TDriveNumber) iRemovedDrive );
       
   525 #else
       
   526             iDBManager->OpenDatabaseL( (TDriveNumber) aData );
       
   527 #endif // RD_MULTIPLE_DRIVE
       
   528             break;
       
   529             }
       
   530         case EUSBMassStorageStartEvent:
       
   531             {
       
   532             iIdle->Cancel();
       
   533             CancelScan();
       
   534 #ifdef RD_MULTIPLE_DRIVE
       
   535             // Close all databases other than the phone memory database
       
   536             for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
       
   537                 {
       
   538                 if (driveList[driveNum]  && (!iDBManager->IsRemoteDrive(static_cast<TDriveNumber>(driveNum))))
       
   539                     {
       
   540                     if ( driveNum != EDriveC )
       
   541                         {
       
   542                         iDBManager->CloseDatabase( (TDriveNumber) driveNum );
       
   543                         }
       
   544                     }
       
   545                 }
       
   546 #else
       
   547             iDBManager->CloseDatabase( (TDriveNumber) aData );
       
   548 #endif // RD_MULTIPLE_DRIVE
       
   549             break;
       
   550             }
       
   551         case EUSBMassStorageEndEvent:
       
   552             {
       
   553 #ifdef RD_MULTIPLE_DRIVE
       
   554             // Open all databases other than the phone memory
       
   555             for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
       
   556                 {
       
   557                 if (driveList[driveNum] && (!iDBManager->IsRemoteDrive(static_cast<TDriveNumber>(driveNum))))
       
   558                     {
       
   559                     if ( driveNum != EDriveC )
       
   560                         {
       
   561                         iDBManager->OpenDatabaseL( (TDriveNumber) driveNum );
       
   562                         }
       
   563                     }
       
   564                 }
       
   565 #else
       
   566             iDBManager->OpenDatabaseL( (TDriveNumber) aData );
       
   567 #endif // RD_MULTIPLE_DRIVE
       
   568             break;
       
   569             }
       
   570         case EUSBMTPNotActiveEvent: // deliberate fall through
       
   571             {
       
   572             if ( iRefreshing )
       
   573                 {
       
   574                 // Notify clients that refresh is cancelled.
       
   575                 iCollectionUtil->Collection().NotifyL( EMcMsgRefreshEnd, KErrLocked );
       
   576                 }
       
   577             }
       
   578         case EUSBMTPStartEvent:
       
   579             {
       
   580             CancelScan();
       
   581             // nothing to do, db is needed for MTP
       
   582             break;
       
   583             }
       
   584         case EUSBMTPEndEvent:
       
   585             {
       
   586             // nothing to do, db is updated by MTP
       
   587             break;
       
   588             }
       
   589         case EPowerKeyEjectEvent:
       
   590             {
       
   591             CancelScan();
       
   592             break;
       
   593             }
       
   594         default:
       
   595             {
       
   596             MPX_DEBUG1("CCMPXHarvesterFileHandlerImp::HandleSystemEventL Unknown system event!");
       
   597             break;
       
   598             }
       
   599         }
       
   600     }
       
   601 
       
   602 // ---------------------------------------------------------------------------
       
   603 // Add a file to the harvester db
       
   604 // ---------------------------------------------------------------------------
       
   605 //
       
   606 CMPXMedia* CMPXHarvesterFileHandlerImp::AddFileL( const TDesC& aPath )
       
   607     {
       
   608     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFileL <---");
       
   609 
       
   610     // Create the media properties and add as usual.
       
   611     //
       
   612     CMPXMedia* prop = iMetadataScanner->ExtractFileL( aPath );
       
   613     CleanupStack::PushL( prop );
       
   614     AddFileL( *prop );
       
   615     CleanupStack::Pop( prop );
       
   616 
       
   617     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFileL --->");
       
   618     return prop;
       
   619     }
       
   620 
       
   621 // ---------------------------------------------------------------------------
       
   622 // Add a file to the harvester db
       
   623 // ---------------------------------------------------------------------------
       
   624 //
       
   625 TInt CMPXHarvesterFileHandlerImp::AddFileL( CMPXMedia& aMediaProp )
       
   626     {
       
   627     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFileL <---");
       
   628 
       
   629     // Parse
       
   630     TPtrC path = aMediaProp.ValueText( TMPXAttribute( KMPXMediaIdGeneral,
       
   631                                                        EMPXMediaGeneralUri) );
       
   632     TInt r(0);
       
   633     // Make sure we have a "file"
       
   634     if( path.Compare(KNullDesC) )
       
   635         {
       
   636         // Last modified time
       
   637         TTime lastModTime;
       
   638         iFs.Modified( path, lastModTime );
       
   639 
       
   640         // Collection UID,
       
   641         CMPXCollectionMediator* mediator = CMPXCollectionMediator::NewL();
       
   642         CleanupStack::PushL( mediator );
       
   643         mediator->CheckItemL( aMediaProp );
       
   644         CleanupStack::PopAndDestroy( mediator );
       
   645 
       
   646         TUid col( KNullUid );
       
   647         if( aMediaProp.IsSupported( TMPXAttribute( KMPXMediaIdGeneral,
       
   648                                                     EMPXMediaGeneralCollectionId ) ) )
       
   649             {
       
   650             col = aMediaProp.ValueTObjectL<TUid>( TMPXAttribute(
       
   651                                                   KMPXMediaIdGeneral,
       
   652                                                   EMPXMediaGeneralCollectionId ) );
       
   653             }
       
   654         MPX_DEBUG2("CMPXHarvesterFileHandlerImp::AddFileL aMediaProp->Value<TUid> col = %i", col.iUid);
       
   655         // Collection not set yet
       
   656         if( col.iUid == 0 )
       
   657             {
       
   658             TInt index = IsMediaFileL( path );
       
   659             if( index >= KErrNone )
       
   660                 {
       
   661                 MPX_DEBUG2(_L("CMPXHarvesterFileHandlerImp::AddFileL - count: %i"),iSupportedTypes.Count());
       
   662                 col = iSupportedTypes[index]->Uid();
       
   663                 MPX_DEBUG2(_L("CMPXHarvesterFileHandlerImp::AddFileL Selected Collection %i"), col.iUid);
       
   664                 aMediaProp.SetTObjectValueL<TUid>( TMPXAttribute(
       
   665                                                     KMPXMediaIdGeneral,
       
   666                                                     EMPXMediaGeneralCollectionId ),
       
   667                                                     col );
       
   668                 }
       
   669             }
       
   670 
       
   671         // drm
       
   672         TBool drm(EFalse);
       
   673         if( aMediaProp.IsSupported( TMPXAttribute(KMPXMediaIdDrm,
       
   674                                                    EMPXMediaDrmProtected) ) )
       
   675             {
       
   676             if( aMediaProp.ValueTObjectL<TBool>(TMPXAttribute(KMPXMediaIdDrm,
       
   677                                                  EMPXMediaDrmProtected)) )
       
   678                 {
       
   679                 TInt rights( EMPXDrmRightsFull );
       
   680 
       
   681                 if( aMediaProp.IsSupported( TMPXAttribute(KMPXMediaIdDrm,
       
   682                                                            EMPXMediaDrmRightsStatus) ) )
       
   683                     {
       
   684                     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFiles -- getting rights");
       
   685                     rights = aMediaProp.ValueTObjectL<TInt>( TMPXAttribute(KMPXMediaIdDrm,
       
   686                                                                      EMPXMediaDrmRightsStatus) );
       
   687                     }
       
   688                 MPX_DEBUG2("CMPXHarvesterFileHandlerImp::AddFiles -- rights %i", rights);
       
   689                 if( rights == EMPXDrmRightsMissing ||
       
   690                     rights == EMPXDrmRightsExpired )
       
   691                     {
       
   692                     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFiles -- drm");
       
   693                     drm = ETrue;
       
   694                     }
       
   695                 }
       
   696             }
       
   697         if( aMediaProp.IsSupported(KMPXMediaGeneralFlags) )
       
   698             {
       
   699             MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFiles -- db flags");
       
   700             TUint dbflags( aMediaProp.ValueTObjectL<TUint>(KMPXMediaGeneralFlags) );
       
   701             if( dbflags&KMPXMediaGeneralFlagsIsDrmLicenceInvalid )
       
   702                 {
       
   703                 MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFiles -- db flags drm invalid");
       
   704                 drm = ETrue;
       
   705                 }
       
   706             }
       
   707         // Add to database
       
   708         CMPXHarvesterDB& db = iDBManager->GetDatabaseL( ::ExtractDrive( path ) );
       
   709         CMPXHarvesterDatabaseTable* table = db.OpenFileL( path );
       
   710         CleanupStack::PushL( table );
       
   711 
       
   712         // Don't add something we already have
       
   713         //
       
   714         if( table->CountL() == 0 )
       
   715             {
       
   716             TParsePtrC parse( path );
       
   717             table->AddItemL( parse.DriveAndPath(), parse.NameAndExt(),
       
   718                              lastModTime, col.iUid, drm );
       
   719             }
       
   720         CleanupStack::PopAndDestroy( table );
       
   721 
       
   722         // Return the collection that it should belong to.
       
   723         r = col.iUid;
       
   724         }
       
   725     else
       
   726         {
       
   727         // No file path, leave KErrArgument!
       
   728         User::Leave( KErrArgument );
       
   729         }
       
   730 
       
   731     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFileL --->");
       
   732     return r;
       
   733     }
       
   734 
       
   735 // ---------------------------------------------------------------------------
       
   736 // Remove a file from the harvester db
       
   737 // ---------------------------------------------------------------------------
       
   738 //
       
   739 TInt CMPXHarvesterFileHandlerImp::RemoveFileL( const TDesC& aPath, TBool aEndTransaction )
       
   740     {
       
   741     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RemoveFileL <---");
       
   742     TInt r(0);
       
   743 
       
   744     // Open the db
       
   745     CMPXHarvesterDB& db = iDBManager->GetDatabaseL( ::ExtractDrive(aPath) );
       
   746 	MPX_PERF_START( MPX_PERF_HARV_DB_DELETE_SUB1 );
       
   747     CMPXHarvesterDatabaseTable* table = db.OpenFileL( aPath );
       
   748     MPX_PERF_END( MPX_PERF_HARV_DB_DELETE_SUB1 );
       
   749 
       
   750     CleanupStack::PushL( table );
       
   751 
       
   752     // Create a cached copy of the db
       
   753 	MPX_PERF_START( MPX_PERF_HARV_DB_DELETE_SUB2 );
       
   754     RPointerArray<CMPXHarvesterDbItem>* ary =
       
   755                                            table->CreateTableRepresentationL();
       
   756     TCleanupItem cleanup( CleanupArray, ary );
       
   757     CleanupStack::PushL( cleanup );
       
   758     MPX_PERF_END( MPX_PERF_HARV_DB_DELETE_SUB2 );
       
   759 
       
   760     // Delete the item from db
       
   761     MPX_PERF_START( MPX_PERF_HARV_DB_DELETE_SUB3 );
       
   762     TRAPD( err, table->DeleteItemL(aEndTransaction) );
       
   763     MPX_PERF_END( MPX_PERF_HARV_DB_DELETE_SUB3 );
       
   764 
       
   765     // If delete was successful, that means the item existed
       
   766     // find the collection db id for return
       
   767     //
       
   768     if( err == KErrNone )
       
   769         {
       
   770         CMPXHarvesterDbItem* item = (*ary)[0];
       
   771         if( item != NULL )
       
   772             {
       
   773             r = item->iColId;
       
   774             }
       
   775         }
       
   776     else
       
   777         {
       
   778         r=err;
       
   779         }
       
   780     CleanupStack::Pop( ary );
       
   781     ary->ResetAndDestroy();
       
   782     delete ary;
       
   783     CleanupStack::PopAndDestroy( table );
       
   784 
       
   785     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RemoveFileL --->");
       
   786     return r;
       
   787     }
       
   788 
       
   789 // ---------------------------------------------------------------------------
       
   790 // Update the properties of a file
       
   791 // ---------------------------------------------------------------------------
       
   792 //
       
   793 void CMPXHarvesterFileHandlerImp::UpdateFileL( const TDesC& aFile, TInt aCollection )
       
   794     {
       
   795     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::UpdateFileL <---");
       
   796 
       
   797     OpenDBForPathL( aFile );
       
   798 
       
   799      // Last modified time
       
   800     TTime lastModTime;
       
   801     iFs.Modified( aFile, lastModTime );
       
   802 
       
   803     iCurTable->UpdateItemL( lastModTime, aCollection,!iRefreshing );
       
   804     Reset();
       
   805     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::UpdateFileL --->");
       
   806     }
       
   807 
       
   808 // ---------------------------------------------------------------------------
       
   809 // Rename a file
       
   810 // ---------------------------------------------------------------------------
       
   811 //
       
   812 void CMPXHarvesterFileHandlerImp::RenameFileL( const TDesC& aOldPath,
       
   813                                                const TDesC& aNewPath,
       
   814                                                TInt aCollection )
       
   815     {
       
   816     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RenameFileL <---");
       
   817 
       
   818     // update harvester database
       
   819     OpenDBForPathL( aOldPath );
       
   820 
       
   821      // Last modified time
       
   822     TTime lastModTime;
       
   823     iFs.Modified( aNewPath, lastModTime );
       
   824 
       
   825     iCurTable->UpdateItemL( lastModTime, aCollection, !iRefreshing, aNewPath );
       
   826     Reset();
       
   827 
       
   828     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RenameFileL --->");
       
   829     }
       
   830 
       
   831 // ---------------------------------------------------------------------------
       
   832 // Finds the associated collection id for a file
       
   833 // ---------------------------------------------------------------------------
       
   834 //
       
   835 TInt CMPXHarvesterFileHandlerImp::FindCollectionIdL( const TDesC& aFile )
       
   836     {
       
   837     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::FindCollectionIdL <---");
       
   838     TInt r(0);
       
   839 
       
   840     // Open the db
       
   841     CMPXHarvesterDB& db = iDBManager->GetDatabaseL( ::ExtractDrive(aFile) );
       
   842     CMPXHarvesterDatabaseTable* table = db.OpenFileL( aFile );
       
   843     CleanupStack::PushL( table );
       
   844 
       
   845     // Create a cached copy of the db
       
   846     RPointerArray<CMPXHarvesterDbItem>* ary =
       
   847                                            table->CreateTableRepresentationL();
       
   848     if( ary->Count() > 0 )
       
   849         {
       
   850         CMPXHarvesterDbItem* item = (*ary)[0];  // not owned
       
   851         r = item->iColId;
       
   852         }
       
   853     else
       
   854         {
       
   855         r = KErrNotFound;
       
   856         }
       
   857     ary->ResetAndDestroy();
       
   858     delete ary;
       
   859     CleanupStack::PopAndDestroy( table );
       
   860 
       
   861     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::FindCollectionIdL --->");
       
   862     return r;
       
   863     }
       
   864 
       
   865 
       
   866 // ---------------------------------------------------------------------------
       
   867 // Re-create all databases
       
   868 // ---------------------------------------------------------------------------
       
   869 //
       
   870 void CMPXHarvesterFileHandlerImp::RecreateDatabases()
       
   871     {
       
   872     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RecreateDatabasesL <--");
       
   873     iDBManager->RecreateDatabases();
       
   874     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RecreateDatabasesL -->");
       
   875     }
       
   876 
       
   877 // ---------------------------------------------------------------------------
       
   878 // Close database transaction
       
   879 // ---------------------------------------------------------------------------
       
   880 //
       
   881 void CMPXHarvesterFileHandlerImp::CloseTransactionL()
       
   882     {
       
   883     iDBManager->CommitL();
       
   884     }
       
   885 
       
   886 // ---------------------------------------------------------------------------
       
   887 // Get a media object for the file
       
   888 // ---------------------------------------------------------------------------
       
   889 //
       
   890 CMPXMedia* CMPXHarvesterFileHandlerImp::GetMediaForFileL( const TDesC& aPath )
       
   891     {
       
   892     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::GetMediaForFileL <---");
       
   893 
       
   894     // Create the media properties
       
   895     //
       
   896     CMPXMedia* prop = iMetadataScanner->ExtractFileL( aPath );
       
   897 
       
   898     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::GetMediaForFileL --->");
       
   899     return prop;
       
   900     }
       
   901 
       
   902 // ---------------------------------------------------------------------------
       
   903 // Get Collection Uid for the file
       
   904 // ---------------------------------------------------------------------------
       
   905 //
       
   906 TInt CMPXHarvesterFileHandlerImp::GetColUidForFileL( const TDesC& aPath )
       
   907     {
       
   908     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::GetColUidForFileL <---");
       
   909 
       
   910     if(aPath == KNullDesC)
       
   911         {
       
   912         // No file path, leave KErrArgument!
       
   913         User::Leave( KErrArgument );
       
   914         }
       
   915 
       
   916     TInt ret(0);
       
   917     TInt index = IsMediaFileL( aPath );
       
   918     if( index >= KErrNone )
       
   919         {
       
   920         ret = iSupportedTypes[index]->Uid().iUid;
       
   921         }
       
   922 
       
   923     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::GetColUidForFileL --->");
       
   924     return ret;
       
   925     }
       
   926 
       
   927 // ---------------------------------------------------------------------------
       
   928 // Remove multiple files from the harvester db
       
   929 // ---------------------------------------------------------------------------
       
   930 //
       
   931 void CMPXHarvesterFileHandlerImp::RemoveFilesL( const MDesCArray& aFilePaths )
       
   932     {
       
   933     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RemoveFilesL <---");
       
   934 
       
   935     TInt count( aFilePaths.MdcaCount() );
       
   936     TBool endTransaction(EFalse);
       
   937     for( TInt i=0; i<count; ++i )
       
   938         {
       
   939         if ( (i == count-1) || (i%KBatchCommit == 0) )
       
   940             {
       
   941             endTransaction = ETrue;
       
   942             }
       
   943         User::LeaveIfError( RemoveFileL( aFilePaths.MdcaPoint(i), endTransaction ) );
       
   944         }
       
   945 
       
   946     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RemoveFilesL --->");
       
   947     }
       
   948 
       
   949 // ---------------------------------------------------------------------------
       
   950 // Remove all files from the harvester db
       
   951 // ---------------------------------------------------------------------------
       
   952 //
       
   953 void CMPXHarvesterFileHandlerImp::RemoveAllFilesL()
       
   954     {
       
   955     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RemoveAllFilesL <---");
       
   956     TInt dbCount( iDBManager->Count() );
       
   957     for( TInt i=0; i< dbCount; ++i )
       
   958         {
       
   959         CMPXHarvesterDB& db = iDBManager->GetDatabaseL( i );
       
   960         db.RemoveAllFilesL();
       
   961         }
       
   962     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::RemoveAllFilesL --->");
       
   963     }
       
   964 
       
   965 // ---------------------------------------------------------------------------
       
   966 // Handles a state change event
       
   967 // ---------------------------------------------------------------------------
       
   968 //
       
   969 void CMPXHarvesterFileHandlerImp::HandleScanStateCompleteL( TScanState aState,
       
   970                                                             TInt aErr )
       
   971     {
       
   972     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleScanStateCompleteL <---");
       
   973 
       
   974     // Cleanup associated with each state
       
   975     //
       
   976     switch( aState )
       
   977         {
       
   978         case EScanFiles:
       
   979             {
       
   980 #ifdef __PRINTDB__
       
   981             if( iCurTable )
       
   982                 iCurTable->PrintItemsInTableL();
       
   983 #endif //__PRINTDB__
       
   984 
       
   985             // Look for removed items
       
   986             // Do not look for removed files if there was an error
       
   987             if( aErr == KErrNone )
       
   988                 {
       
   989                 HandleBrokenItemsL();
       
   990                 }
       
   991             Reset();
       
   992             break;
       
   993             }
       
   994         case ECleanupBrokenLink:
       
   995             {
       
   996             iBrokenLink->Reset();
       
   997             break;
       
   998             }
       
   999         case EScanPlaylists:
       
  1000             {
       
  1001             iPlaylistScanner->Reset();
       
  1002             break;
       
  1003             }
       
  1004         case EScanMetadata:
       
  1005             {
       
  1006             iMetadataScanner->Reset();
       
  1007             break;
       
  1008             }
       
  1009         default:
       
  1010             break;
       
  1011         }
       
  1012 
       
  1013     // Next state handling
       
  1014     //
       
  1015     if( KErrNone == aErr )
       
  1016         {
       
  1017         switch( aState )
       
  1018             {
       
  1019             case EScanFiles:
       
  1020                 {
       
  1021                 MPX_DEBUG1("Start Broken Link");
       
  1022                 iBrokenLink->Start();
       
  1023                 break;
       
  1024                 }
       
  1025             case ECleanupBrokenLink:
       
  1026                 {
       
  1027                 MPX_DEBUG1("Start Metadata Scan");
       
  1028                 iMetadataScanner->Start();
       
  1029                 break;
       
  1030                 }
       
  1031             case EScanMetadata:
       
  1032                 {
       
  1033                 MPX_DEBUG1("Start Metadata Scan");
       
  1034                 iPlaylistScanner->ScanL();
       
  1035                 break;
       
  1036                 }
       
  1037             case EScanPlaylists:
       
  1038                 {
       
  1039                 MPX_DEBUG1("Scan complete");
       
  1040                 
       
  1041                 TRAPD(err, DoCompleteRefreshL( KErrNone ));
       
  1042                 
       
  1043                 // handle DoCompleteRefreshL leave
       
  1044                 if( err != KErrNone )
       
  1045                     {
       
  1046                     // finish refresh, close waitnote
       
  1047                     iCollectionUtil->Collection().NotifyL( EMcMsgRefreshEnd, err );
       
  1048                     }
       
  1049                 
       
  1050                 // Reset all scan states
       
  1051                 Reset();
       
  1052                 break;
       
  1053                 }
       
  1054             default:
       
  1055                 break;
       
  1056             }
       
  1057         }
       
  1058     else
       
  1059         {
       
  1060         // Error occured, check for out of disk
       
  1061         //
       
  1062         TInt error = iOutOfDisk ? KErrDiskFull : aErr;
       
  1063         TRAPD(err, DoCompleteRefreshL( error ));
       
  1064         
       
  1065         // handle DoCompleteRefreshL leave
       
  1066         if( err != KErrNone )
       
  1067             {
       
  1068             // finish refresh, close waitnote
       
  1069             iCollectionUtil->Collection().NotifyL( EMcMsgRefreshEnd, err );
       
  1070             }
       
  1071         }
       
  1072     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleScanStateCompleteL <---");
       
  1073     }
       
  1074 
       
  1075 // ---------------------------------------------------------------------------
       
  1076 // Handles a state change event
       
  1077 // ---------------------------------------------------------------------------
       
  1078 //
       
  1079 void CMPXHarvesterFileHandlerImp::HandleSynchronizationComplete( TInt aErr )
       
  1080     {
       
  1081     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleSynchronizationComplete enter");
       
  1082 
       
  1083     iSynchronizing = EFalse;
       
  1084 
       
  1085     if(aErr == KErrNone)
       
  1086         {
       
  1087         // Start the scanning process
       
  1088         iRefreshCount++;
       
  1089         // Keep a count of how many we added to syncrhonize the number
       
  1090         iAddedCount = 0;
       
  1091         iRefreshing = ETrue;
       
  1092 
       
  1093         TRAPD(err,iFolderScanner->ScanL( iFilteredDrivesToScan ));
       
  1094         if(err == KErrNone)
       
  1095             {
       
  1096             iMetadataScanner->Reset();
       
  1097             iBrokenLink->Reset();
       
  1098             iPlaylistScanner->Reset();
       
  1099             iIdle->Cancel();
       
  1100             }
       
  1101         else
       
  1102             {
       
  1103             TRAPD(error, DoCompleteRefreshL( err ));
       
  1104             
       
  1105             // handle DoCompleteRefreshL leave
       
  1106             if( error != KErrNone )
       
  1107                 {
       
  1108                 // finish refresh, close waitnote
       
  1109                 TRAP_IGNORE( iCollectionUtil->Collection().NotifyL( EMcMsgRefreshEnd, error ) );
       
  1110                 }
       
  1111             }        
       
  1112         }
       
  1113     else
       
  1114         {
       
  1115         iRefreshCount++;
       
  1116         iRefreshing = ETrue;
       
  1117         TInt error = iOutOfDisk ? KErrDiskFull : aErr;
       
  1118         TRAPD(err, DoCompleteRefreshL( error ));
       
  1119         
       
  1120         // handle DoCompleteRefreshL leave
       
  1121         if( err != KErrNone )
       
  1122             {
       
  1123             // finish refresh, close waitnote
       
  1124             TRAP_IGNORE( iCollectionUtil->Collection().NotifyL( EMcMsgRefreshEnd, err ) );
       
  1125             }
       
  1126         }
       
  1127     MPX_DEBUG1("<--- CMPXHarvesterFileHandlerImp::HandleSynchronizationCompleteL exit");
       
  1128     }
       
  1129 
       
  1130 // ---------------------------------------------------------------------------
       
  1131 // Handle adding a single file
       
  1132 // ---------------------------------------------------------------------------
       
  1133 //
       
  1134 void CMPXHarvesterFileHandlerImp::HandleFileAdditionL( const TDesC& aFileName,
       
  1135                                                        TInt /*aColIndex*/,
       
  1136                                                        TBool /*aPlaylist*/ )
       
  1137     {
       
  1138     MPX_DEBUG2("CMPXHarvesterFileHandlerImp::HandleFileAdditionL %S<---", &aFileName );
       
  1139 
       
  1140     // Find the item in the array
       
  1141     //
       
  1142     CMPXHarvesterDbItem tmp;
       
  1143     tmp.iFile = aFileName.AllocL();
       
  1144 
       
  1145     // Last modified time
       
  1146     //
       
  1147     TTime lastModTime;
       
  1148     iFs.Modified( aFileName, lastModTime );
       
  1149 
       
  1150     // This is very inefficient, should hash.
       
  1151     //
       
  1152     if( iCurList )
       
  1153         {
       
  1154         TInt index = iCurList->FindInOrder( &tmp, CMPXHarvesterDbItem::Compare );
       
  1155         if( index != KErrNotFound )
       
  1156             {
       
  1157             MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleFileAdditionL found file");
       
  1158 
       
  1159             // Check modified time stamp to see if it was modified
       
  1160             // Also check files that did not have rights, see if we have rights now
       
  1161             //
       
  1162             CMPXHarvesterDbItem* item = (*iCurList)[index];
       
  1163             if( item->iLastModifiedTime != lastModTime || item->iDrm )
       
  1164                 {
       
  1165                 MPX_DEBUG1("Rescanning a file because of modified or drm");
       
  1166                 HandleUpdatedItemL( aFileName );
       
  1167                 }
       
  1168 
       
  1169             // If found, we remove it from the list, items left should be deleted
       
  1170             //
       
  1171             delete item;
       
  1172             iCurList->Remove( index );
       
  1173             }
       
  1174         else  // new file
       
  1175             {
       
  1176             HandleNewItemL( aFileName );
       
  1177             }
       
  1178         }
       
  1179     else
       
  1180         {
       
  1181         MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleFileAdditionL Scan cancelled");
       
  1182         }
       
  1183 
       
  1184     delete tmp.iFile;
       
  1185     tmp.iFile = NULL;
       
  1186 
       
  1187     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleFileAdditionL --->");
       
  1188     }
       
  1189 
       
  1190 // ---------------------------------------------------------------------------
       
  1191 // Handle a change in the file system, could be a file added/removed
       
  1192 // ---------------------------------------------------------------------------
       
  1193 //
       
  1194 void CMPXHarvesterFileHandlerImp::HandleDirectoryChangedL( const TDesC& aPath )
       
  1195     {
       
  1196     // Delay the scanning for a few seconds so the files are finished
       
  1197     // copying. If already active, means we just append onto the list
       
  1198     //
       
  1199     iAutoScanPaths.AppendL( aPath );
       
  1200     if( !iIdle->IsActive() )
       
  1201         {
       
  1202         TCallBack cb( Callback, this );
       
  1203         iIdle->Start( TTimeIntervalMicroSeconds32( KAutoScanDelay ),
       
  1204                       TTimeIntervalMicroSeconds32( KAutoScanAfter ),
       
  1205                       cb );
       
  1206         }
       
  1207 
       
  1208     }
       
  1209 
       
  1210 // ---------------------------------------------------------------------------
       
  1211 // Handles opening the drive
       
  1212 // ---------------------------------------------------------------------------
       
  1213 //
       
  1214 void CMPXHarvesterFileHandlerImp::HandleOpenDriveL( TDriveNumber aDrive,
       
  1215                                                     const TDesC& aFolder )
       
  1216     {
       
  1217 #ifdef __PRINTDB__
       
  1218     if( iCurTable )
       
  1219         iCurTable->PrintItemsInTableL();
       
  1220 #endif //__PRINTDB__
       
  1221 
       
  1222     // Look for broken files
       
  1223     HandleBrokenItemsL();
       
  1224 
       
  1225     // Delete previous table and open the next one
       
  1226     Reset();
       
  1227     MPX_TRAPD( err, iCurDB = &iDBManager->GetDatabaseL( aDrive ) );
       
  1228     if ( err != KErrNone )
       
  1229         {
       
  1230         iDBManager->OpenAllDatabasesL();
       
  1231         iCurDB = &iDBManager->GetDatabaseL( aDrive );
       
  1232         }
       
  1233     
       
  1234     if( iDrivesToScan.Find( aFolder ) != KErrNotFound )
       
  1235         {
       
  1236         iCurTable = iCurDB->OpenAllFilesTableL();
       
  1237         }
       
  1238     else
       
  1239         {
       
  1240         iCurTable = iCurDB->OpenDirectoryL( aFolder );
       
  1241         }
       
  1242     iCurList = iCurTable->CreateTableRepresentationL();
       
  1243     }
       
  1244 
       
  1245 // ---------------------------------------------------------------------------
       
  1246 // Is this a media file we are interested in
       
  1247 // ---------------------------------------------------------------------------
       
  1248 //
       
  1249 TInt CMPXHarvesterFileHandlerImp::IsMediaFileL( const TDesC& aFile )
       
  1250     {
       
  1251     MPX_DEBUG2("CMPXHarvesterFileHandlerImp::IsMediaFileL %S <---", &aFile);
       
  1252 
       
  1253     TParsePtrC parse( aFile );
       
  1254     TInt index(KErrNotFound);
       
  1255     TInt count( iSupportedTypes.Count() );
       
  1256     for (TInt i=0; i <count; ++i)
       
  1257         {
       
  1258         TInt index2(KErrNotFound);
       
  1259         const CDesCArray& exts = iSupportedTypes[i]->Extensions();
       
  1260         if (!exts.FindIsq(parse.Ext(), index2))
       
  1261             { // found
       
  1262             index = i;
       
  1263             break;
       
  1264             }
       
  1265         }
       
  1266 
       
  1267     if( index == KErrNotFound )
       
  1268         {
       
  1269         index = IsPlaylistFileL( aFile ) ? ETrue : KErrNotFound;
       
  1270         }
       
  1271 
       
  1272     MPX_DEBUG2("CMPXHarvesterFileHandlerImp::IsMediaFileL %i --->", index);
       
  1273     return index;
       
  1274     }
       
  1275 
       
  1276 // ---------------------------------------------------------------------------
       
  1277 // Is this a playlist file we are interested in
       
  1278 // ---------------------------------------------------------------------------
       
  1279 //
       
  1280 TInt CMPXHarvesterFileHandlerImp::IsPlaylistFileL( const TDesC& aFile )
       
  1281     {
       
  1282     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::IsPlaylistFileL <---");
       
  1283     return iPlaylistScanner->IsPlaylistFileL( aFile );
       
  1284     }
       
  1285 
       
  1286 // ---------------------------------------------------------------------------
       
  1287 // Checks if this path is in the blocked list
       
  1288 // ---------------------------------------------------------------------------
       
  1289 //
       
  1290 TBool CMPXHarvesterFileHandlerImp::IsPathBlockedL( const TDesC& aPath )
       
  1291     {
       
  1292     TInt count( iPathsToBlock.Count() );
       
  1293     TBool isBlocked(EFalse);
       
  1294     HBufC* buf = aPath.AllocLC();
       
  1295     TPtr ptr = buf->Des();
       
  1296     ptr.UpperCase();
       
  1297     for( TInt i=0; i<count; ++i )
       
  1298         {
       
  1299         if( ptr.Find( iPathsToBlock[i] ) != KErrNotFound )
       
  1300             {
       
  1301             isBlocked = ETrue;
       
  1302             break;
       
  1303             }
       
  1304         }
       
  1305     CleanupStack::PopAndDestroy( buf );
       
  1306     return isBlocked;
       
  1307     }
       
  1308 
       
  1309 // ---------------------------------------------------------------------------
       
  1310 // Adds multiple files to the collection
       
  1311 // ---------------------------------------------------------------------------
       
  1312 //
       
  1313 void CMPXHarvesterFileHandlerImp::AddFilesToCollectionL(
       
  1314                                                 CMPXMediaArray& aMediaArray )
       
  1315     {
       
  1316     MPX_DEBUG1("MPXHarvesterFileHandlerImp::AddFilesToCollectionL <---");
       
  1317 
       
  1318     // Add to collection db
       
  1319     CMPXCollectionMediator* mediator =
       
  1320                 CMPXCollectionMediator::NewL( iCollectionUtil->Collection(),
       
  1321                                               this );
       
  1322     CleanupStack::PushL( mediator );
       
  1323     TRAPD( addErr, mediator->AddItemL( aMediaArray ) );
       
  1324     CleanupStack::PopAndDestroy( mediator );
       
  1325 
       
  1326     // Now we add them to the harvester db
       
  1327     //
       
  1328     if( addErr == KErrNone )
       
  1329         {
       
  1330         TInt count = aMediaArray.Count();
       
  1331         for( TInt i=0; i<count; ++i )
       
  1332             {
       
  1333             const TDesC& path = aMediaArray.AtL(i)->ValueText( TMPXAttribute(
       
  1334                                                                 KMPXMediaIdGeneral,
       
  1335                                                                 EMPXMediaGeneralUri ) );
       
  1336             OpenDBForPathL( path );
       
  1337 
       
  1338             // Collection
       
  1339             const TUid& collection = aMediaArray.AtL(i)->ValueTObjectL<TUid>(
       
  1340                                    TMPXAttribute( KMPXMediaIdGeneral,
       
  1341                                                   EMPXMediaGeneralCollectionId ) );
       
  1342 
       
  1343             // Last modified time
       
  1344             TTime lastModTime;
       
  1345             iFs.Modified( path, lastModTime );
       
  1346 
       
  1347             // drm
       
  1348             TBool drm(EFalse);
       
  1349             if( aMediaArray[i]->IsSupported( TMPXAttribute(KMPXMediaIdDrm,
       
  1350                                                      EMPXMediaDrmProtected) ) &&
       
  1351                 aMediaArray.AtL(i)->ValueTObjectL<TBool>(TMPXAttribute(KMPXMediaIdDrm,
       
  1352                                                      EMPXMediaDrmProtected)) )
       
  1353                 {
       
  1354                 TInt rights = EMPXDrmRightsFull;
       
  1355                 if( aMediaArray[i]->IsSupported( TMPXAttribute(KMPXMediaIdDrm,
       
  1356                                                                EMPXMediaDrmRightsStatus)) )
       
  1357                     {
       
  1358                     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFilesToCollectionL -- getting rights");
       
  1359                     rights =  aMediaArray.AtL(i)->ValueTObjectL<TInt>(
       
  1360                               TMPXAttribute(KMPXMediaIdDrm, EMPXMediaDrmRightsStatus) );
       
  1361                     }
       
  1362                 if( rights == EMPXDrmRightsMissing ||
       
  1363                     rights == EMPXDrmRightsExpired )
       
  1364                     {
       
  1365                     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddFilesToCollectionL -- rights missing/expired");
       
  1366                     drm = ETrue;
       
  1367                     }
       
  1368                 }
       
  1369 
       
  1370             TParsePtrC parse( path );
       
  1371             iCurTable->AddItemL( parse.DriveAndPath(),
       
  1372                                  parse.NameAndExt(),
       
  1373                                  lastModTime, collection.iUid, drm );
       
  1374 
       
  1375             iAddedCount++;
       
  1376             }
       
  1377         }
       
  1378     else if ( addErr == KErrDiskFull )
       
  1379         {
       
  1380         User::Leave( KErrDiskFull );
       
  1381         }
       
  1382 
       
  1383     MPX_DEBUG1("MPXHarvesterFileHandlerImp::AddFilesToCollectionL --->");
       
  1384     }
       
  1385 
       
  1386 // ---------------------------------------------------------------------------
       
  1387 // Updates some files to the collection
       
  1388 // ---------------------------------------------------------------------------
       
  1389 //
       
  1390 void CMPXHarvesterFileHandlerImp::UpdatesFilesInCollectionL(
       
  1391                                                  CMPXMediaArray& aMediaArray )
       
  1392     {
       
  1393     MPX_DEBUG1("MPXHarvesterFileHandlerImp::UpdatesFilesInCollectionL <---");
       
  1394 
       
  1395     // Do not update files which still do not have rights
       
  1396     //
       
  1397     TInt c( aMediaArray.Count() );
       
  1398     for( TInt i=0; i<c; ++i )
       
  1399         {
       
  1400         TInt rights = EMPXDrmRightsFull;
       
  1401 
       
  1402         if( aMediaArray.AtL(i)->IsSupported( KMPXMediaDrmRightsStatus ) )
       
  1403             {
       
  1404             rights = aMediaArray.AtL(i)->ValueTObjectL<TInt>( KMPXMediaDrmRightsStatus );
       
  1405             }
       
  1406         if( rights == EMPXDrmRightsMissing )
       
  1407             {
       
  1408             aMediaArray.Remove(i);
       
  1409             i--;
       
  1410             c--;
       
  1411             }
       
  1412         }
       
  1413 
       
  1414     // Update collection db
       
  1415     CMPXCollectionMediator* mediator =
       
  1416                 CMPXCollectionMediator::NewL( iCollectionUtil->Collection(),
       
  1417                                               this );
       
  1418     CleanupStack::PushL( mediator );
       
  1419     TRAPD( setErr , mediator->SetItemL( aMediaArray ) );
       
  1420     CleanupStack::PopAndDestroy( mediator );
       
  1421 
       
  1422     // Now we update them to the harvester db
       
  1423     //
       
  1424     if( setErr == KErrNone )
       
  1425         {
       
  1426         TInt count( aMediaArray.Count() );
       
  1427         for( TInt i=0; i<count; ++i )
       
  1428             {
       
  1429             const TDesC& filepath = aMediaArray.AtL(i)->ValueText( KMPXMediaGeneralUri );
       
  1430             OpenDBForPathL( filepath );
       
  1431 
       
  1432             // Collection
       
  1433             TUid collection = aMediaArray.AtL(i)->ValueTObjectL<TUid>( KMPXMediaGeneralCollectionId );
       
  1434             // Last modified time
       
  1435             TTime lastModTime;
       
  1436             iFs.Modified( filepath, lastModTime );
       
  1437 
       
  1438             // drm
       
  1439             TBool drm(EFalse);
       
  1440             if( aMediaArray.AtL(i)->IsSupported(KMPXMediaDrmProtected)  &&
       
  1441                 aMediaArray.AtL(i)->ValueTObjectL<TBool>(KMPXMediaDrmProtected) )
       
  1442                 {
       
  1443                 TInt rights = EMPXDrmRightsFull;
       
  1444 
       
  1445                 if( aMediaArray.AtL(i)->IsSupported(KMPXMediaDrmRightsStatus) )
       
  1446                     {
       
  1447                     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::UpdateFilesToCollectionL -- getting rights");
       
  1448                     rights = aMediaArray.AtL(i)->ValueTObjectL<TInt>(KMPXMediaDrmRightsStatus);
       
  1449                     }
       
  1450                 if( rights == EMPXDrmRightsMissing ||
       
  1451                     rights == EMPXDrmRightsExpired )
       
  1452                     {
       
  1453                     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::UpdateFilesToCollectionL -- updating rights");
       
  1454                     drm = ETrue;
       
  1455                     }
       
  1456                 }
       
  1457 
       
  1458             iCurTable->UpdateItemL( filepath, lastModTime, collection.iUid, drm, !iRefreshing );
       
  1459             }
       
  1460         }
       
  1461     else if ( setErr == KErrDiskFull )
       
  1462         {
       
  1463         User::Leave( KErrDiskFull );
       
  1464         }
       
  1465 
       
  1466     MPX_DEBUG1("MPXHarvesterFileHandlerImp::UpdatesFilesInCollectionL --->");
       
  1467     }
       
  1468 
       
  1469 // ---------------------------------------------------------------------------
       
  1470 // Updates the db based on mediator decisions
       
  1471 // ---------------------------------------------------------------------------
       
  1472 //
       
  1473 void CMPXHarvesterFileHandlerImp::HandleMediatorPathUpdatedL(
       
  1474                                                          CMPXMedia*& aProperty,
       
  1475                                                          TUid  /*aOldPath*/  )
       
  1476     {
       
  1477     MPX_DEBUG1("MPXHarvesterFileHandlerImp::UpdatesFilesInCollectionL <---");
       
  1478 
       
  1479     // Update harvester database based on mediator changes
       
  1480     //
       
  1481     const TDesC& filepath = aProperty->ValueText( KMPXMediaGeneralUri );
       
  1482     OpenDBForPathL( filepath );
       
  1483 
       
  1484     // Collection
       
  1485     //
       
  1486     TUid colUid = aProperty->ValueTObjectL<TUid>( KMPXMediaGeneralCollectionId );
       
  1487 
       
  1488     // Last modified time
       
  1489     //
       
  1490     TTime lastModTime;
       
  1491     iFs.Modified( filepath, lastModTime );
       
  1492 
       
  1493     // Update DB, only if the record existed. No record means this is a new
       
  1494     // entry
       
  1495     if( iCurTable->CountL() )
       
  1496         {
       
  1497         iCurTable->UpdateItemL( lastModTime, colUid.iUid, !iRefreshing );
       
  1498         }
       
  1499 
       
  1500     MPX_DEBUG1("MPXHarvesterFileHandlerImp::UpdatesFilesInCollectionL <---");
       
  1501     }
       
  1502 
       
  1503 // ---------------------------------------------------------------------------
       
  1504 // Add playlists to the collection
       
  1505 // ---------------------------------------------------------------------------
       
  1506 //
       
  1507 void CMPXHarvesterFileHandlerImp::AddPlaylistToCollectionL(
       
  1508                                                  CMPXMediaArray& aMediaArray )
       
  1509     {
       
  1510     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddPlaylistToCollectionL <---");
       
  1511 
       
  1512     //
       
  1513     // add to collection one by one to avoid the following scenario:
       
  1514     // 2 playlists to add to the collection. The 1st one is successfully
       
  1515     // added but the 2nd playlist isn't. When AddL leaves, it does not
       
  1516     // indicate which one is successfully added and which one isn't.
       
  1517     // As a result, the successfully added playlist isn't added to
       
  1518     // harvester database and during the next scan, it will be picked
       
  1519     // up again and added to the database with auto-numbered title.
       
  1520     //
       
  1521     TInt count( aMediaArray.Count() );
       
  1522     for (TInt i=0; i<count; ++i)
       
  1523         {
       
  1524         CMPXMedia* media = aMediaArray.AtL(i);
       
  1525 
       
  1526         TRAPD(addErr, DoCommandL( KMPXCommandIdCollectionAdd,
       
  1527                                   media->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId),
       
  1528                                   TMPXAttribute(KMPXCommandColAddMedia),
       
  1529                                   media,
       
  1530                                   ETrue  ) );
       
  1531 
       
  1532         // Now we add the item to the harvester db
       
  1533         //
       
  1534         if( addErr == KErrNone )
       
  1535             {
       
  1536             const TDesC& path =
       
  1537                 media->ValueText( TMPXAttribute( KMPXMediaIdGeneral, EMPXMediaGeneralUri ) );
       
  1538             OpenDBForPathL( path );
       
  1539 
       
  1540             // Collection
       
  1541             TUid collection =
       
  1542                 media->ValueTObjectL<TUid>( TMPXAttribute( KMPXMediaIdGeneral, EMPXMediaGeneralCollectionId ) );
       
  1543 
       
  1544             // Last modified time
       
  1545             TTime lastModTime;
       
  1546             iFs.Modified( path, lastModTime );
       
  1547 
       
  1548             TParsePtrC parse( path );
       
  1549             iCurTable->AddItemL( parse.DriveAndPath(),
       
  1550                                  parse.NameAndExt(),
       
  1551                                  lastModTime, collection.iUid, EFalse );
       
  1552             iAddedCount++;
       
  1553             }
       
  1554         else if ( addErr == KErrDiskFull )
       
  1555             {
       
  1556             User::Leave( KErrDiskFull );
       
  1557             }
       
  1558         }
       
  1559 
       
  1560     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::AddPlaylistToCollectionL --->");
       
  1561     }
       
  1562 
       
  1563 // ---------------------------------------------------------------------------
       
  1564 // Update Playlists in the collection
       
  1565 // ---------------------------------------------------------------------------
       
  1566 //
       
  1567 void CMPXHarvesterFileHandlerImp::UpdatePlaylistToCollectionL(
       
  1568                                                  CMPXMediaArray& aMediaArray )
       
  1569     {
       
  1570     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::UpdatePlaylistToCollectionL <---");
       
  1571 
       
  1572     // Update the collection
       
  1573     //
       
  1574     TInt count( aMediaArray.Count() );
       
  1575     for (TInt i=0; i<count; ++i)
       
  1576         {
       
  1577         CMPXMedia* media = aMediaArray.AtL(i);
       
  1578 
       
  1579         TRAPD( setErr, DoCommandL( KMPXCommandIdCollectionSet,
       
  1580                                    media->ValueTObjectL<TUid>(KMPXMediaGeneralCollectionId),
       
  1581                                    KMPXCommandColSetMedia,
       
  1582                                    media,
       
  1583                                    ETrue ) );
       
  1584 
       
  1585         // Now we update them to the harvester db
       
  1586         //
       
  1587         if( setErr == KErrNone )
       
  1588             {
       
  1589             const TDesC& filepath =
       
  1590                 media->ValueText( TMPXAttribute( KMPXMediaIdGeneral, EMPXMediaGeneralUri ) );
       
  1591             OpenDBForPathL( filepath );
       
  1592 
       
  1593             // Collection
       
  1594             const TUid& collection =
       
  1595                 media->ValueTObjectL<TUid>( TMPXAttribute( KMPXMediaIdGeneral, EMPXMediaGeneralCollectionId ) );
       
  1596 
       
  1597             // Last modified time
       
  1598             TTime lastModTime;
       
  1599             iFs.Modified( filepath, lastModTime );
       
  1600 
       
  1601             iCurTable->UpdateItemL( filepath, lastModTime, collection.iUid, EFalse, !iRefreshing);
       
  1602             }
       
  1603         else if ( setErr == KErrDiskFull )
       
  1604             {
       
  1605             User::Leave( KErrDiskFull );
       
  1606             }
       
  1607         }
       
  1608 
       
  1609     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::UpdatePlaylistToCollectionL --->");
       
  1610     }
       
  1611 
       
  1612 // ---------------------------------------------------------------------------
       
  1613 // Handle low disk events
       
  1614 // ---------------------------------------------------------------------------
       
  1615 //
       
  1616 void CMPXHarvesterFileHandlerImp::HandleLowDiskEvent( TInt /*aDrive*/ )
       
  1617     {
       
  1618     // Cancel the scanning process, set low disk flag to true
       
  1619     iOutOfDisk = ETrue;
       
  1620     CancelScan();
       
  1621     }
       
  1622 
       
  1623 // ---------------------------------------------------------------------------
       
  1624 // Handle Broken Links
       
  1625 // ---------------------------------------------------------------------------
       
  1626 //
       
  1627 void CMPXHarvesterFileHandlerImp::HandleBrokenLinkL( MDesCArray& aFileArray,
       
  1628                                                      RArray<TInt>& aColIds ,
       
  1629                                                      RPointerArray<CMPXHarvesterDB>& aDbs,
       
  1630                                                      TInt aCount )
       
  1631     {
       
  1632     // Common local variables
       
  1633     //
       
  1634     RArray<TInt> contId;
       
  1635     CleanupClosePushL( contId );
       
  1636     contId.AppendL( KMPXMediaIdGeneral );
       
  1637     contId.AppendL( KMPXMediaIdContainer );
       
  1638 
       
  1639     RArray<TInt> itemId;
       
  1640     CleanupClosePushL( itemId );
       
  1641     itemId.AppendL( KMPXMediaIdGeneral );
       
  1642 
       
  1643     // Remove from Collection db
       
  1644     //
       
  1645     CMPXMediaArray* musicArray = CMPXMediaArray::NewL();
       
  1646     CleanupStack::PushL( musicArray );
       
  1647     CMPXMediaArray* podcastArray = CMPXMediaArray::NewL();
       
  1648     CleanupStack::PushL( podcastArray );
       
  1649 
       
  1650     for(TInt j=0; j<aCount; ++j )
       
  1651         {
       
  1652         TPtrC uri(aFileArray.MdcaPoint(j));
       
  1653         TUid uid = TUid::Uid( aColIds[j] );
       
  1654 
       
  1655         MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleBrokenLinkL -- \
       
  1656                     Want to remove an item");
       
  1657         MPX_DEBUG2("%S", &uri);
       
  1658         if (!(IsPlaylistFileL( uri )))
       
  1659             {
       
  1660             // Construct a CMPXMedia to represent the deleted object
       
  1661             CMPXMedia* media = CMPXMedia::NewL( itemId.Array() );
       
  1662             CleanupStack::PushL( media );
       
  1663             media->SetTObjectValueL<TMPXGeneralType>(KMPXMediaGeneralType,
       
  1664                                                      EMPXItem);
       
  1665             media->SetTextValueL( KMPXMediaGeneralUri,
       
  1666                                   uri );
       
  1667             media->SetTObjectValueL<TMPXGeneralCategory>(KMPXMediaGeneralCategory,
       
  1668                                                          EMPXSong );
       
  1669             media->SetTObjectValueL<TUid>( KMPXMediaGeneralCollectionId,
       
  1670                                            uid );
       
  1671             if( uid == iMusicCollectionId )
       
  1672                 {
       
  1673                 musicArray->AppendL( media );
       
  1674                 }
       
  1675             else
       
  1676                 {
       
  1677                 podcastArray->AppendL( media );
       
  1678                 }
       
  1679             CleanupStack::Pop( media );  // ownership xfer
       
  1680 
       
  1681             // Cleanup harvester DB
       
  1682             aDbs[j]->DeleteFileL( uri );
       
  1683             }
       
  1684         else
       
  1685             {
       
  1686             OpenDBForPathL( uri );
       
  1687 
       
  1688             //  Last modified time
       
  1689             TTime lastModTime;
       
  1690             lastModTime.HomeTime();
       
  1691 
       
  1692             iCurTable->UpdateItemL(uri, lastModTime, uid.iUid, EFalse);
       
  1693             }
       
  1694         }
       
  1695 
       
  1696     //  Package the media array and send to collection
       
  1697     //
       
  1698     if( musicArray->Count() )
       
  1699         {
       
  1700         CMPXMedia* rootMedia = CMPXMedia::NewL( contId.Array() );
       
  1701         CleanupStack::PushL( rootMedia );
       
  1702         rootMedia->SetTObjectValueL<TMPXGeneralType>( KMPXMediaGeneralType, EMPXGroup );
       
  1703         rootMedia->SetTObjectValueL<TMPXGeneralCategory>( KMPXMediaGeneralCategory, EMPXCollection );
       
  1704         rootMedia->SetCObjectValueL<CMPXMediaArray>( KMPXMediaArrayContents, musicArray );
       
  1705         rootMedia->SetTObjectValueL<TInt>( KMPXMediaArrayCount, musicArray->Count() );
       
  1706         DoRemoveL( rootMedia, iMusicCollectionId );
       
  1707         CleanupStack::PopAndDestroy( rootMedia );
       
  1708         }
       
  1709     if( podcastArray->Count() )
       
  1710         {
       
  1711         CMPXMedia* rootMedia = CMPXMedia::NewL( contId.Array() );
       
  1712         CleanupStack::PushL( rootMedia );
       
  1713         rootMedia->SetTObjectValueL<TMPXGeneralType>( KMPXMediaGeneralType, EMPXGroup );
       
  1714         rootMedia->SetTObjectValueL<TMPXGeneralCategory>( KMPXMediaGeneralCategory, EMPXCollection );
       
  1715         rootMedia->SetCObjectValueL<CMPXMediaArray>( KMPXMediaArrayContents, podcastArray );
       
  1716         rootMedia->SetTObjectValueL<TInt>( KMPXMediaArrayCount, podcastArray->Count() );
       
  1717         DoRemoveL( rootMedia, iPodcastCollectionId );
       
  1718         CleanupStack::PopAndDestroy( rootMedia );
       
  1719         }
       
  1720 
       
  1721     // Cleanup
       
  1722     //
       
  1723     CleanupStack::PopAndDestroy( podcastArray );
       
  1724     CleanupStack::PopAndDestroy( musicArray );
       
  1725 
       
  1726     contId.Reset();
       
  1727     itemId.Reset();
       
  1728     CleanupStack::PopAndDestroy( &itemId );
       
  1729     CleanupStack::PopAndDestroy( &contId );
       
  1730     }
       
  1731 
       
  1732 // ---------------------------------------------------------------------------
       
  1733 // Parses cenrep setting for scan paths
       
  1734 // ---------------------------------------------------------------------------
       
  1735 //
       
  1736 void CMPXHarvesterFileHandlerImp::ParseScanPathL()
       
  1737     {
       
  1738     // Gets the string from cenrep, use default if leave
       
  1739     // string should be in the form 'item1' 'item2'
       
  1740     //
       
  1741     TBuf<255> scanPath;
       
  1742     TBuf<255> blockPath;
       
  1743     CRepository* cenrep(NULL);
       
  1744     TRAPD( err, cenrep = CRepository::NewL( KCRUIDHarvesterFeatures ) );
       
  1745     if( err == KErrNone )
       
  1746         {
       
  1747         cenrep->Get( KHarvesterScanPathKey, scanPath );
       
  1748         cenrep->Get( KHarvesterBlockPathKey, blockPath );
       
  1749         delete cenrep;
       
  1750         }
       
  1751     else
       
  1752         {
       
  1753         scanPath = KDefaultScanPath;
       
  1754         blockPath = KDefaultBlockPath;
       
  1755         }
       
  1756 
       
  1757     MPX_DEBUG2("ParseScanPathL scanPaths: %S", &scanPath);
       
  1758     MPX_DEBUG2("ParseScanPathL blockPaths: %S", &blockPath);
       
  1759     ::ExtractTokensL( scanPath, iDrivesToScan );
       
  1760     ::ExtractTokensL( blockPath, iPathsToBlock );
       
  1761     }
       
  1762 
       
  1763 // ---------------------------------------------------------------------------
       
  1764 // Parses cenrep setting for container file types
       
  1765 // ---------------------------------------------------------------------------
       
  1766 //
       
  1767 void CMPXHarvesterFileHandlerImp::ParseContainersL()
       
  1768     {
       
  1769     TBuf<255> containers;
       
  1770     CRepository* cenrep( NULL );
       
  1771     TRAPD( err, cenrep = CRepository::NewL( KCRUIDHarvesterFeatures ) );
       
  1772     if( err == KErrNone )
       
  1773         {
       
  1774         cenrep->Get( KHarvesterContainerKey, containers );
       
  1775         delete cenrep;
       
  1776         }
       
  1777     else
       
  1778         {
       
  1779         containers = KDefaultContainers;
       
  1780         }
       
  1781 
       
  1782     MPX_DEBUG2("Container types: %S", &containers);
       
  1783     ::ExtractTokensL( containers, *iContainerTypes);
       
  1784     }
       
  1785 
       
  1786 // ---------------------------------------------------------------------------
       
  1787 // Parses cenrep setting for automatic scan folders
       
  1788 // ---------------------------------------------------------------------------
       
  1789 //
       
  1790 void CMPXHarvesterFileHandlerImp::ParseAutoScanL()
       
  1791     {
       
  1792     // Make sure we don't insert duplicates
       
  1793     iFolderMonitors.ResetAndDestroy();
       
  1794 
       
  1795     TBuf<255> folders;
       
  1796     CRepository* cenrep( NULL );
       
  1797     TRAPD( err, cenrep = CRepository::NewL( KCRUIDHarvesterFeatures ) );
       
  1798     if( err == KErrNone )
       
  1799         {
       
  1800         err = cenrep->Get( KAutoScanDirectoryKey, folders );
       
  1801         delete cenrep;
       
  1802         }
       
  1803     if( err != KErrNone )
       
  1804         {
       
  1805         folders = KDefaultAutoScanFolder;
       
  1806         }
       
  1807 
       
  1808     MPX_DEBUG2("AutoScanFolders: %S", &folders);
       
  1809 
       
  1810     CDesCArrayFlat* array = new(ELeave) CDesCArrayFlat(2);
       
  1811     CleanupStack::PushL( array );
       
  1812     ::ExtractTokensL( folders, *array);
       
  1813 
       
  1814     TInt count( array->Count() );
       
  1815     for( TInt i=0; i<count; ++i )
       
  1816         {
       
  1817         CMPXFolderMonitor* monitor = CMPXFolderMonitor::NewL( *this, iFs );
       
  1818         CleanupStack::PushL( monitor );
       
  1819         iFolderMonitors.AppendL( monitor );  // ownership xfer
       
  1820         CleanupStack::Pop( monitor );
       
  1821         monitor->StartL( array->MdcaPoint(i) );
       
  1822         }
       
  1823     CleanupStack::PopAndDestroy( array );
       
  1824     }
       
  1825 
       
  1826 // ---------------------------------------------------------------------------
       
  1827 // Resets the scanning table and array
       
  1828 // ---------------------------------------------------------------------------
       
  1829 //
       
  1830 void CMPXHarvesterFileHandlerImp::Reset()
       
  1831     {
       
  1832     delete iCurTable;
       
  1833     iCurTable = NULL;
       
  1834 
       
  1835     if( iCurList )
       
  1836         {
       
  1837         iCurList->ResetAndDestroy();
       
  1838         delete iCurList;
       
  1839         iCurList = NULL;
       
  1840         }
       
  1841     iCurDB = NULL; // not owned
       
  1842     }
       
  1843 
       
  1844 // ---------------------------------------------------------------------------
       
  1845 // Handles a new file added to the collection
       
  1846 // ---------------------------------------------------------------------------
       
  1847 //
       
  1848 void CMPXHarvesterFileHandlerImp::HandleNewItemL( const TDesC& aFileName )
       
  1849     {
       
  1850     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleNewItemL new file");
       
  1851 
       
  1852     // Add it to the database
       
  1853     //
       
  1854     if( IsPlaylistFileL( aFileName ) )
       
  1855         {
       
  1856         iPlaylistScanner->AddPlaylistToScanL( aFileName );
       
  1857         }
       
  1858     else
       
  1859         {
       
  1860         iMetadataScanner->AddNewFileToScanL( aFileName );
       
  1861         }
       
  1862     }
       
  1863 
       
  1864 // ---------------------------------------------------------------------------
       
  1865 // Handles broken items
       
  1866 // ---------------------------------------------------------------------------
       
  1867 //
       
  1868 void CMPXHarvesterFileHandlerImp::HandleBrokenItemsL()
       
  1869     {
       
  1870     // Add the item to the broken links list
       
  1871     //
       
  1872     if( iCurList )
       
  1873         {
       
  1874         TInt count( iCurList->Count() );
       
  1875         for( TInt i=0; i<count; ++i )
       
  1876             {
       
  1877             TPtrC filename = (*iCurList)[i]->iFile->Des();
       
  1878             TInt colId = (*iCurList)[i]->iColId;
       
  1879             iBrokenLink->AddBrokenLinkL( filename, colId, iCurDB );
       
  1880             }
       
  1881         }
       
  1882     }
       
  1883 
       
  1884 // ---------------------------------------------------------------------------
       
  1885 // Handles Updated items
       
  1886 // ---------------------------------------------------------------------------
       
  1887 //
       
  1888 void CMPXHarvesterFileHandlerImp::HandleUpdatedItemL( const TDesC& aFile )
       
  1889     {
       
  1890     TBool playlist = IsPlaylistFileL( aFile );
       
  1891     if( playlist )
       
  1892         {
       
  1893         iPlaylistScanner->AddUpdatedPlaylistToScanL( aFile );
       
  1894         }
       
  1895     else
       
  1896         {
       
  1897         iMetadataScanner->AddModifiedFileToScanL( aFile );
       
  1898         }
       
  1899     }
       
  1900 
       
  1901 // ---------------------------------------------------------------------------
       
  1902 // Finds the associated collection for a file
       
  1903 // ---------------------------------------------------------------------------
       
  1904 //
       
  1905 TInt CMPXHarvesterFileHandlerImp::CollectionForExtensionL( const TDesC& aFile )
       
  1906     {
       
  1907     TInt index = IsMediaFileL( aFile );
       
  1908     TInt val(0);
       
  1909     if( KErrNotFound != index )
       
  1910         {
       
  1911         const CMPXCollectionType& type = *iSupportedTypes[index];
       
  1912         val = type.Uid().iUid;
       
  1913         }
       
  1914     return val;
       
  1915     }
       
  1916 
       
  1917 // ---------------------------------------------------------------------------
       
  1918 // Setup the internal variables when opening a path
       
  1919 // ---------------------------------------------------------------------------
       
  1920 //
       
  1921 void CMPXHarvesterFileHandlerImp::OpenDBForPathL( const TDesC& aPath )
       
  1922     {
       
  1923     Reset();
       
  1924     TDriveNumber num = ::ExtractDrive( aPath );
       
  1925     iCurDB = &iDBManager->GetDatabaseL( num );
       
  1926     iCurTable = iCurDB->OpenFileL( aPath );
       
  1927     }
       
  1928 
       
  1929 // ---------------------------------------------------------------------------
       
  1930 // Complete a refreshing event
       
  1931 // ---------------------------------------------------------------------------
       
  1932 //
       
  1933 void CMPXHarvesterFileHandlerImp::DoCompleteRefreshL( TInt aErr )
       
  1934 
       
  1935     {
       
  1936     // If no error or cancel, return the final number of items added
       
  1937     MPX_DEBUG2("Scan error %i", aErr );
       
  1938     
       
  1939     // Reopen databases (in case we removed them for out of disk drives before scan)
       
  1940     iDBManager->OpenAllDatabasesL();
       
  1941     
       
  1942     if( aErr == KErrNone )
       
  1943         {
       
  1944         // Commit the changes on databases in transaction
       
  1945         iDBManager->CommitL();
       
  1946         }
       
  1947     else
       
  1948         {
       
  1949         // Rollback the changes on databases in transaction
       
  1950         iDBManager->Rollback();
       
  1951         }
       
  1952 
       
  1953     if( aErr == KErrNone || aErr == KErrCancel )
       
  1954         {
       
  1955         aErr = iAddedCount;
       
  1956         }
       
  1957     
       
  1958     if (iFilteredDrivesToScan.Count() != iDrivesToScan.Count())
       
  1959         {
       
  1960         aErr = KErrDiskFull; 
       
  1961         }
       
  1962 
       
  1963     if( iRefreshing )
       
  1964         {
       
  1965         iCollectionUtil->Collection().NotifyL( EMcMsgRefreshEnd, aErr );
       
  1966         }
       
  1967     iRefreshCount--;
       
  1968     if ( iRefreshCount < 0 )
       
  1969         {
       
  1970         iRefreshCount = 0;
       
  1971         }
       
  1972     if( iCollectionUtil && (iRefreshCount == 0) )
       
  1973         {
       
  1974         iCollectionUtil->Close();
       
  1975         iCollectionUtil = NULL;
       
  1976         }
       
  1977     iRefreshing = EFalse;
       
  1978 
       
  1979     // Cancel disk monitors
       
  1980     TInt c (iDiskMonitors.Count());
       
  1981     iOutOfDisk = EFalse;
       
  1982 
       
  1983     for( TInt i=0; i<c; ++i )
       
  1984         {
       
  1985         iDiskMonitors[i]->Cancel();
       
  1986         }
       
  1987     }
       
  1988 
       
  1989 // ---------------------------------------------------------------------------
       
  1990 // Issue a command to the collection
       
  1991 // ---------------------------------------------------------------------------
       
  1992 //
       
  1993 void CMPXHarvesterFileHandlerImp::DoCommandL( TInt aCommandId,
       
  1994                                               TUid aCollectionId,
       
  1995                                               const TMPXAttribute& aMediaAttribute,
       
  1996                                               CMPXMedia* aMedia,
       
  1997                                               TBool aSync )
       
  1998     {
       
  1999     CMPXCommand* cmd = CMPXCommand::NewL();
       
  2000     CleanupStack::PushL( cmd );
       
  2001 
       
  2002     cmd->SetTObjectValueL( KMPXCommandGeneralId, aCommandId );
       
  2003     cmd->SetTObjectValueL( KMPXCommandGeneralCollectionId, aCollectionId.iUid );
       
  2004     cmd->SetTObjectValueL( KMPXCommandGeneralDoSync, aSync );
       
  2005     if( aMedia )
       
  2006         {
       
  2007         cmd->SetCObjectValueL<CMPXMedia>( aMediaAttribute, aMedia );
       
  2008         }
       
  2009 
       
  2010 
       
  2011     iCollectionUtil->Collection().CommandL( *cmd );
       
  2012     CleanupStack::PopAndDestroy( cmd );
       
  2013     }
       
  2014 
       
  2015 // ---------------------------------------------------------------------------
       
  2016 // Remove an item from the collection
       
  2017 // ---------------------------------------------------------------------------
       
  2018 //
       
  2019 void CMPXHarvesterFileHandlerImp::DoRemoveL( CMPXMedia* aMedia, TUid aCollectionId )
       
  2020     {
       
  2021     CMPXCommand* cmd = CMPXCommand::NewL();
       
  2022     CleanupStack::PushL( cmd );
       
  2023 
       
  2024     cmd->SetTObjectValueL( KMPXCommandGeneralId, KMPXCommandIdCollectionRemoveMedia );
       
  2025     cmd->SetTObjectValueL( KMPXCommandGeneralDoSync, ETrue );
       
  2026     cmd->SetTObjectValueL( KMPXCommandCollectionRemoveMediaDeleteRecord, ETrue );
       
  2027     cmd->SetTObjectValueL( KMPXCommandGeneralCollectionId, aCollectionId.iUid );
       
  2028     cmd->SetCObjectValueL<CMPXMedia>( KMPXCommandCollectionRemoveMedia, aMedia );
       
  2029 
       
  2030     iCollectionUtil->Collection().CommandL( *cmd );
       
  2031     CleanupStack::PopAndDestroy( cmd );
       
  2032     }
       
  2033 
       
  2034 // ---------------------------------------------------------------------------
       
  2035 // Check DB logical synchronization
       
  2036 // ---------------------------------------------------------------------------
       
  2037 //
       
  2038 TBool CMPXHarvesterFileHandlerImp::CheckDbInSyncL()
       
  2039     {
       
  2040     ASSERT(iCollectionUtil != NULL);
       
  2041     TBool needsync(EFalse);
       
  2042     RArray<TInt> dbDrives;
       
  2043 
       
  2044     TInt dbCount(iDBManager->Count());
       
  2045     for(TInt i=0; i < dbCount; ++i)
       
  2046         {
       
  2047         TInt harv_count = 0; //records count from harvester database
       
  2048         TInt coll_count = 0; //records count from collection database
       
  2049 
       
  2050         CMPXHarvesterDB& db = iDBManager->GetDatabaseL(i);
       
  2051         TDriveNumber drive = db.GetDbDrive();
       
  2052         harv_count = db.CountAllFilesL();
       
  2053 
       
  2054         //get count from music db
       
  2055         coll_count = GetTrackCountL(drive,iMusicCollectionId.iUid,EMPXCollectionCountTotal);
       
  2056 
       
  2057         if ( !iDisablePodcasting )
       
  2058             {
       
  2059             //get count from podcast db
       
  2060             coll_count += GetTrackCountL(drive,iPodcastCollectionId.iUid,EMPXCollectionCountTrack);
       
  2061             }
       
  2062 
       
  2063         if(harv_count != coll_count)
       
  2064             {
       
  2065             needsync = ETrue;
       
  2066             dbDrives.Append(drive);
       
  2067             }
       
  2068         }
       
  2069 
       
  2070     if(needsync)
       
  2071         {
       
  2072         iDbSynchronizer->Synchronize(dbDrives,iCollectionUtil);
       
  2073         }
       
  2074     dbDrives.Close();
       
  2075 
       
  2076     return needsync;
       
  2077     }
       
  2078 
       
  2079 // ---------------------------------------------------------------------------
       
  2080 // Idle callback from CPerioidic
       
  2081 // ---------------------------------------------------------------------------
       
  2082 //
       
  2083 TInt CMPXHarvesterFileHandlerImp::Callback( TAny* aPtr )
       
  2084     {
       
  2085     TBool rtn(EFalse);
       
  2086     TRAP_IGNORE( rtn = ((CMPXHarvesterFileHandlerImp*)aPtr)->DoAutoScanL() ); //lint !e665
       
  2087     return rtn; // done
       
  2088     }
       
  2089 
       
  2090 // ---------------------------------------------------------------------------
       
  2091 // Perform the automatic scan event
       
  2092 // ---------------------------------------------------------------------------
       
  2093 //
       
  2094 TBool CMPXHarvesterFileHandlerImp::DoAutoScanL()
       
  2095     {
       
  2096     TBool again(EFalse);
       
  2097     // Make sure to create a collection utility instance if it has not been
       
  2098     //
       
  2099     if( !iCollectionUtil )
       
  2100         {
       
  2101         iCollectionUtil = MMPXCollectionUtility::NewL( NULL, KMusicPlayerUid );
       
  2102         }
       
  2103 
       
  2104     if( !iRefreshing && !iSynchronizing )
       
  2105         {
       
  2106         // Add a path to scan
       
  2107         iRefreshCount++;
       
  2108         CancelScan();
       
  2109         Reset();
       
  2110         iFolderScanner->ScanL( iAutoScanPaths );
       
  2111 
       
  2112         // Cleanup
       
  2113         iAutoScanPaths.Reset();
       
  2114         iIdle->Cancel();
       
  2115         }
       
  2116     else
       
  2117         {
       
  2118         again = ETrue;
       
  2119         }
       
  2120 
       
  2121     return again;
       
  2122     }
       
  2123 
       
  2124 // ---------------------------------------------------------------------------
       
  2125 // Get track count for given table in the db
       
  2126 // ---------------------------------------------------------------------------
       
  2127 //
       
  2128 TInt CMPXHarvesterFileHandlerImp::GetTrackCountL(TDriveNumber aDrive,TInt aColDbId, TInt aColTable)
       
  2129     {
       
  2130     TInt count(0);
       
  2131 
       
  2132     //get count from music db
       
  2133     CMPXCommand* cmdCountM = CMPXMedia::NewL();
       
  2134     CleanupStack::PushL(cmdCountM);
       
  2135     cmdCountM->SetTObjectValueL<TMPXCommandId>(KMPXCommandGeneralId, KMPXCommandCollectionGetCount);
       
  2136     cmdCountM->SetTObjectValueL<TBool>(KMPXCommandGeneralDoSync, ETrue);
       
  2137     cmdCountM->SetTObjectValueL<TInt>(KMPXCommandGeneralCollectionId, aColDbId);
       
  2138     cmdCountM->SetTObjectValueL<TInt>(KMPXCommandCollectionCountDrive, aDrive);
       
  2139     cmdCountM->SetTObjectValueL<TInt>(KMPXCommandCollectionCountTable, aColTable);
       
  2140 
       
  2141     iCollectionUtil->Collection().CommandL(*cmdCountM);
       
  2142 
       
  2143     // returned command should contain count
       
  2144     if (!cmdCountM->IsSupported(KMPXCommandCollectionCountValue))
       
  2145         {
       
  2146         User::Leave(KErrAbort);
       
  2147         }
       
  2148 
       
  2149     count = cmdCountM->ValueTObjectL<TInt>(KMPXCommandCollectionCountValue);
       
  2150     CleanupStack::PopAndDestroy(cmdCountM);
       
  2151 
       
  2152     return count;
       
  2153     }
       
  2154 
       
  2155 // ---------------------------------------------------------------------------
       
  2156 // Event callback from MDRMEventObserver
       
  2157 // ---------------------------------------------------------------------------
       
  2158 //
       
  2159 void CMPXHarvesterFileHandlerImp::HandleEventL( MDRMEvent* aEvent )
       
  2160     {
       
  2161     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleEventL <---");
       
  2162     CDRMEventAddRemove *event  = reinterpret_cast<CDRMEventAddRemove*>(aEvent);
       
  2163  
       
  2164     if( event->Status() == ERightsObjectRecieved ) 
       
  2165         {
       
  2166         HBufC8 *url = event->GetContentIDL();
       
  2167         CleanupStack::PushL(url);
       
  2168         // Convert 8 bit data to 16 bit.
       
  2169         TBufC<ContentAccess::KMaxCafUniqueId> rightsCid;
       
  2170         TPtr cidPtr( rightsCid.Des() );
       
  2171         cidPtr.Copy( url->Des() );
       
  2172         
       
  2173         // get list of files with DRM flag set
       
  2174         RPointerArray<CMPXHarvesterDbItem>* list = GetDrmFilesL();
       
  2175         CleanupStack::PushL( list );
       
  2176 
       
  2177         // match incoming rights to the correct file
       
  2178         TBool found = EFalse;
       
  2179         for ( TInt i=0; i<list->Count(); i++ )
       
  2180             {
       
  2181             CMPXHarvesterDbItem* item = (*list)[i];
       
  2182             CContent* content = CContent::NewL( item->iFile->Des() );
       
  2183             CleanupStack::PushL( content );
       
  2184             CData* data = content->OpenContentL( EPeek );
       
  2185             CleanupStack::PushL( data );
       
  2186             
       
  2187             // Get content ID from file
       
  2188             TInt err = KErrNone;
       
  2189             TPtr cid( NULL, 0 );
       
  2190             HBufC* uniqueId( HBufC::NewLC( ContentAccess::KMaxCafUniqueId ) );
       
  2191             cid.Set( uniqueId->Des() );
       
  2192             err = data->GetStringAttribute( ContentAccess::EContentID, cid );
       
  2193             if ( (err == KErrNone ) && (cid.Compare( cidPtr ) == 0) )
       
  2194                 {
       
  2195                 // Add file for metadata scanning
       
  2196                 iMetadataScanner->AddModifiedFileToScanL( item->iFile->Des() );
       
  2197                 found = ETrue;
       
  2198                 }
       
  2199             CleanupStack::PopAndDestroy( 3 );  // uniqueId, data, content
       
  2200             }
       
  2201         
       
  2202         // Start metadata scanning if match found
       
  2203         if ( found )
       
  2204             {
       
  2205             if( !iCollectionUtil )
       
  2206                 {
       
  2207                 iCollectionUtil = MMPXCollectionUtility::NewL( NULL, KMusicPlayerUid );
       
  2208                 }
       
  2209             iMetadataScanner->Start();
       
  2210             }
       
  2211         list->ResetAndDestroy();
       
  2212         CleanupStack::PopAndDestroy( list );
       
  2213         CleanupStack::PopAndDestroy( url );
       
  2214         }
       
  2215     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::HandleEventL --->");
       
  2216     }
       
  2217 
       
  2218 // ---------------------------------------------------------------------------
       
  2219 // Get a list of files with DRM flag set from the Harvester DB.
       
  2220 // ---------------------------------------------------------------------------
       
  2221 //
       
  2222 RPointerArray<CMPXHarvesterDbItem>* CMPXHarvesterFileHandlerImp::GetDrmFilesL()
       
  2223     {
       
  2224     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::GetDrmFiles <---");
       
  2225     CMPXHarvesterDB*             db=NULL;     // Current db reference
       
  2226     CMPXHarvesterDatabaseTable*  table=NULL;  // owned, must delete
       
  2227     RPointerArray<CMPXHarvesterDbItem>* tempList=NULL;
       
  2228     RPointerArray<CMPXHarvesterDbItem>* drmFileList = new (ELeave) RPointerArray<CMPXHarvesterDbItem>;
       
  2229     
       
  2230     CleanupStack::PushL( drmFileList );
       
  2231 
       
  2232 #ifdef RD_MULTIPLE_DRIVE
       
  2233     TDriveList driveList;
       
  2234     TInt driveCount(0);
       
  2235 
       
  2236     // Get all visible drives
       
  2237     if ( KErrNone == DriveInfo::GetUserVisibleDrives(
       
  2238     		iFs, driveList, driveCount ) )
       
  2239     	{
       
  2240         for( TInt driveNum = EDriveA; driveNum <= EDriveZ; driveNum++ )
       
  2241             {
       
  2242             if ( driveList[driveNum] )
       
  2243                 {
       
  2244             	TDriveNumber drive = (TDriveNumber)driveNum;
       
  2245                 // Get DRM files from database
       
  2246                 db = &iDBManager->GetDatabaseL( drive );
       
  2247                 table = db->OpenDrmFileL(); 
       
  2248                 CleanupStack::PushL( table );
       
  2249                 tempList = table->CreateTableRepresentationL();
       
  2250                 CleanupStack::PushL( tempList );
       
  2251                 // copy content to drm file list
       
  2252                 for ( TInt i=0; i<tempList->Count(); i++ )
       
  2253                     {
       
  2254                     drmFileList->AppendL( (*tempList)[i] );
       
  2255                     }
       
  2256                 // reset
       
  2257                 tempList->Reset();
       
  2258                 CleanupStack::PopAndDestroy( tempList );
       
  2259                 CleanupStack::PopAndDestroy( table );
       
  2260                 }
       
  2261             }
       
  2262     	}
       
  2263 #else
       
  2264     //ensure drive E is ready
       
  2265     //otherwise GetDataBaseL will leave if MMC is removed
       
  2266     if ( IsDriveReady( EDriveE ) )
       
  2267         {
       
  2268         // Get DRM files from database in E drive
       
  2269         db = &iDBManager->GetDatabaseL( EDriveE );
       
  2270         table = db->OpenDrmFileL(); 
       
  2271         CleanupStack::PushL( table );
       
  2272         tempList = table->CreateTableRepresentationL();
       
  2273         CleanupStack::PushL( tempList );
       
  2274         // copy content to drm file list
       
  2275         for ( TInt i=0; i<tempList->Count(); i++ )
       
  2276             {
       
  2277             drmFileList->AppendL( (*tempList)[i] );
       
  2278             }
       
  2279         // reset
       
  2280         tempList->Reset();
       
  2281         CleanupStack::PopAndDestroy( tempList );
       
  2282         CleanupStack::PopAndDestroy( table );
       
  2283         }
       
  2284 
       
  2285     // Get DRM files from database in C drive
       
  2286     db = &iDBManager->GetDatabaseL( EDriveC );
       
  2287     table = db->OpenDrmFileL(); 
       
  2288     CleanupStack::PushL( table );
       
  2289     tempList = table->CreateTableRepresentationL();
       
  2290     CleanupStack::PushL( tempList );
       
  2291     // copy content to iCurList
       
  2292     for ( TInt i=0; i<tempList->Count(); i++ )
       
  2293         {
       
  2294         drmFileList->AppendL( (*tempList)[i] );
       
  2295         }
       
  2296     tempList->Reset();
       
  2297     CleanupStack::PopAndDestroy( tempList );
       
  2298     CleanupStack::PopAndDestroy( table );
       
  2299 #endif
       
  2300     CleanupStack::Pop( drmFileList );
       
  2301     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::GetDrmFiles --->");
       
  2302     return drmFileList;
       
  2303     }
       
  2304 
       
  2305 // ---------------------------------------------------------------------------
       
  2306 // Verifies if aDrive is ready.
       
  2307 // ---------------------------------------------------------------------------
       
  2308 //
       
  2309 TBool CMPXHarvesterFileHandlerImp::IsDriveReady( TDriveNumber aDrive )
       
  2310     {
       
  2311     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::IsDriveReady <---");
       
  2312 
       
  2313     TDriveInfo driveInfo;
       
  2314     TInt error = iFs.Drive( driveInfo, aDrive );
       
  2315     TBool ready = ETrue;
       
  2316     if ( error != KErrNone )
       
  2317         {
       
  2318         ready = EFalse;
       
  2319         }
       
  2320     else if ( driveInfo.iDriveAtt == static_cast<TUint>( KDriveAbsent ) )
       
  2321         {
       
  2322         //aDrive is absent
       
  2323         ready = EFalse;
       
  2324         }
       
  2325     else
       
  2326         {
       
  2327         TVolumeInfo volumeInfo;
       
  2328         TInt errCode = iFs.Volume( volumeInfo, aDrive );
       
  2329         if( errCode != KErrNone )
       
  2330             {
       
  2331             //aDrive is ready for use
       
  2332             ready = EFalse;
       
  2333             }
       
  2334         }
       
  2335 
       
  2336     MPX_DEBUG1("CMPXHarvesterFileHandlerImp::IsDriveReady --->");
       
  2337     return ready;
       
  2338     }
       
  2339 
       
  2340 // END OF FILE