mmappcomponents/harvester/filehandler/src/mpxdbsynchronizer.cpp
changeset 0 a2952bb97e68
equal deleted inserted replaced
-1:000000000000 0:a2952bb97e68
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Class for synchronization collection and harvester databases
       
    15 *
       
    16 */
       
    17 
       
    18 #include <e32base.h>
       
    19 #include <mpxlog.h>
       
    20 #include <mpxcommandgeneraldefs.h>
       
    21 #include <mpxcollectioncommanddefs.h>
       
    22 #include <mpxcollectionutility.h>
       
    23 
       
    24 #include "mpxcommand.h"
       
    25 #include "mpxharvesterdbmanager.h"
       
    26 #include "mpxharvesterdbtable.h"
       
    27 #include "mpxdbsynchronizer.h"
       
    28 #include "mpxdbsyncobserver.h"
       
    29 
       
    30 #include <mpxcollectionplugin.hrh>
       
    31 #include <centralrepository.h>            // to get podcasting cenrep key
       
    32 // CONSTANTS
       
    33 const TInt KRecStepCount = 100;
       
    34 
       
    35 // ======== LOCAL FUNCTIONS ========
       
    36     
       
    37 // ======== MEMBER FUNCTIONS ========
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 // Constructor
       
    41 // ---------------------------------------------------------------------------
       
    42 //
       
    43 CMPXDbSynchronizer::CMPXDbSynchronizer(MMPXDbSyncObserver& aObserver,
       
    44                                        CMPXHarvesterDatabaseManager& aDbMng,
       
    45                                        const TUid& aMusic,
       
    46                                        const TUid& aPodcast,
       
    47                                        RFs& aFs,
       
    48                                        TBool aDisablePodcast )
       
    49         : CActive(EPriorityNull), //using the same priority as folder scanner
       
    50         iSyncObserver(aObserver),
       
    51         iDBManager(aDbMng),
       
    52         iColUtil(NULL),
       
    53         iMusicUid(aMusic),
       
    54         iPodcastUid(aPodcast),
       
    55         iFs(aFs),
       
    56         iSyncState(ESyncStopped),
       
    57         iCurDrive(-1),
       
    58         iDbRecTotalCount(0),
       
    59         iCurDbRecCount(0),
       
    60         iLastID(0),
       
    61         iDisablePodcasting( aDisablePodcast )
       
    62     {
       
    63     CActiveScheduler::Add(this);
       
    64     }
       
    65 
       
    66 // ---------------------------------------------------------------------------
       
    67 // 2nd Phase Constructor
       
    68 // ---------------------------------------------------------------------------
       
    69 //
       
    70 void CMPXDbSynchronizer::ConstructL()
       
    71     {
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 // Two Phased Constructor
       
    76 // ---------------------------------------------------------------------------
       
    77 //
       
    78 CMPXDbSynchronizer* CMPXDbSynchronizer::NewL(MMPXDbSyncObserver& aObserver,
       
    79                                              CMPXHarvesterDatabaseManager& aDbMng,
       
    80                                              const TUid& aMusic,
       
    81                                              const TUid& aPodcast, 
       
    82                                              RFs& aFs,
       
    83                                              TBool aDisablePodcast )
       
    84     {
       
    85     CMPXDbSynchronizer* self = new(ELeave) CMPXDbSynchronizer(aObserver,aDbMng,aMusic,
       
    86                                                               aPodcast,aFs,aDisablePodcast);
       
    87     CleanupStack::PushL(self);
       
    88     self->ConstructL();
       
    89     CleanupStack::Pop(self);
       
    90     return self;
       
    91     }
       
    92 
       
    93 // ---------------------------------------------------------------------------
       
    94 // Destructor
       
    95 // ---------------------------------------------------------------------------
       
    96 //
       
    97 CMPXDbSynchronizer::~CMPXDbSynchronizer()
       
    98     {
       
    99     Cancel();
       
   100     iDbDrives.Close();
       
   101     }
       
   102     
       
   103 // ---------------------------------------------------------------------------
       
   104 // Scans a list of drives for files
       
   105 // ---------------------------------------------------------------------------
       
   106 //
       
   107 void CMPXDbSynchronizer::Synchronize(RArray<TInt>& aDrives, MMPXCollectionUtility* aColUtil)
       
   108     {
       
   109     MPX_DEBUG1("---> CMPXDbSynchronizer::Synchronize");
       
   110     ASSERT(aColUtil != NULL); //internal call, should be always ok
       
   111     
       
   112     iColUtil = aColUtil;
       
   113     
       
   114     //check if synchronization is already active then ignore request
       
   115     if(iSyncState == ESyncStopped)
       
   116         {
       
   117         TInt dbCount(iDBManager.Count());
       
   118         TInt count(aDrives.Count());
       
   119         
       
   120         if(dbCount >= count && count != 0)
       
   121             {
       
   122             for(TInt i=0; i<count; ++i)
       
   123                 {
       
   124                 iDbDrives.Append(aDrives[i]);
       
   125                 }
       
   126 
       
   127             iSyncState = ESyncMusic;
       
   128             
       
   129             // start synchronization cycle
       
   130             CompleteSelf();
       
   131             }
       
   132         else
       
   133             {
       
   134             iSyncObserver.HandleSynchronizationComplete(KErrArgument);
       
   135             }
       
   136         }
       
   137     else
       
   138         {
       
   139         iSyncObserver.HandleSynchronizationComplete(KErrInUse);
       
   140         }
       
   141     
       
   142     MPX_DEBUG1("<--- CMPXDbSynchronizer::Synchronize");
       
   143     }
       
   144 
       
   145 // ---------------------------------------------------------------------------
       
   146 // Sync next portion of data
       
   147 // ---------------------------------------------------------------------------
       
   148 //
       
   149 TBool CMPXDbSynchronizer::DoSynchronizeStepL()
       
   150     {
       
   151     MPX_DEBUG1("---> CMPXDbSynchronizer::DoSynchronizeStepL");
       
   152 
       
   153     TBool ret(EFalse);
       
   154 
       
   155     if(iDbDrives.Count() != 0)
       
   156         {
       
   157         TBool clear(EFalse);
       
   158         //first time for a database on this drive
       
   159         if(iCurDrive == -1)
       
   160             {
       
   161             iCurDrive = iDbDrives[0];
       
   162             clear = ETrue;
       
   163             }
       
   164 
       
   165         CMPXHarvesterDB& db = iDBManager.GetDatabaseL((TDriveNumber)iCurDrive);
       
   166         CMPXHarvesterDatabaseTable* table = db.OpenAllFilesTableL();
       
   167         CleanupStack::PushL(table);
       
   168 
       
   169         if(clear)
       
   170             {
       
   171             db.RemoveAllFilesL();
       
   172             iDbRecTotalCount = 0;
       
   173             iCurDbRecCount = 0;
       
   174             iLastID = 0;
       
   175             }
       
   176 
       
   177         switch(iSyncState)
       
   178             {
       
   179             case ESyncMusic: //now getting music table content from curr drive's db
       
   180                 {
       
   181                 DoMusicTableSyncL(*table);
       
   182                 break;
       
   183                 }
       
   184             case ESyncPlaylist: //now getting playlist table content (music db)
       
   185                 {
       
   186                 DoPlaylistTableSyncL(*table);
       
   187                 break;
       
   188                 }
       
   189             case ESyncPodcast: //now getting podcast table content (podcast db)
       
   190                 {
       
   191                 DoPodcastTableSyncL(*table);
       
   192                 break;
       
   193                 }
       
   194             default:
       
   195                 {
       
   196                 User::Leave(KErrAbort);
       
   197                 }
       
   198             }
       
   199 
       
   200         CleanupStack::PopAndDestroy(table);
       
   201         }
       
   202     else
       
   203         {
       
   204         ret = ETrue; //sync complete
       
   205         }
       
   206     
       
   207     MPX_DEBUG1("<--- CMPXDbSynchronizer::SetupNextDriveToScanL return");
       
   208     return ret;
       
   209     }
       
   210     
       
   211 // ---------------------------------------------------------------------------
       
   212 // Handle when synchronization is complete
       
   213 // ---------------------------------------------------------------------------
       
   214 //
       
   215 void CMPXDbSynchronizer::DoSynchronizeComplete(TInt aErr)
       
   216     {
       
   217     MPX_DEBUG1("---> CMPXDbSynchronizer::DoSynchronizeComplete");
       
   218     
       
   219     iDbDrives.Reset(); // Reset drives
       
   220     iSyncState = ESyncStopped;
       
   221 
       
   222     iCurDrive = -1;
       
   223     iDbRecTotalCount = 0;
       
   224     iCurDbRecCount = 0;
       
   225     
       
   226     // Notify observer
       
   227     iSyncObserver.HandleSynchronizationComplete(aErr);
       
   228     
       
   229     MPX_DEBUG1("<--- CMPXDbSynchronizer::DoSynchronizeComplete");
       
   230     }
       
   231      
       
   232 // ---------------------------------------------------------------------------
       
   233 // From CActive
       
   234 // ---------------------------------------------------------------------------
       
   235 //
       
   236 void CMPXDbSynchronizer::RunL()
       
   237     {
       
   238     MPX_DEBUG1("---> CMPXDbSynchronizer::RunL");
       
   239     
       
   240     TBool done(EFalse);
       
   241     done = DoSynchronizeStepL();
       
   242      
       
   243     if(done)
       
   244         {
       
   245         DoSynchronizeComplete(KErrNone);
       
   246         }
       
   247     else // if( !done )
       
   248         {
       
   249         MPX_DEBUG1("CMPXDbSynchronizer::RunL -- Schedule next run");
       
   250         CompleteSelf();
       
   251         }
       
   252     MPX_DEBUG1("<--- CMPXDbSynchronizer::RunL");
       
   253     }
       
   254 
       
   255 // ---------------------------------------------------------------------------
       
   256 // From CActive
       
   257 // ---------------------------------------------------------------------------
       
   258 //
       
   259 void CMPXDbSynchronizer::DoCancel()
       
   260     {
       
   261     ASSERT(iSyncState != ESyncStopped);
       
   262     DoSynchronizeComplete(KErrCancel);
       
   263     }
       
   264     
       
   265 // ----------------------------------------------------------------------------
       
   266 // Handles a leave occurring in the request completion event handler RunL()
       
   267 // ----------------------------------------------------------------------------
       
   268 //
       
   269 TInt CMPXDbSynchronizer::RunError(TInt aError)
       
   270     {
       
   271     MPX_DEBUG2("CMPXDbSynchronizer::RunError(%d)", aError );
       
   272     
       
   273     DoSynchronizeComplete(aError);
       
   274     
       
   275     return KErrNone;
       
   276     }
       
   277 
       
   278 //Helper functions implementation
       
   279 void CMPXDbSynchronizer::DoMusicTableSyncL(CMPXHarvesterDatabaseTable& aTable)
       
   280     {
       
   281     if(iDbRecTotalCount == 0)
       
   282         {
       
   283         //get total number of records from music db for music table
       
   284         GetTableCountL(iMusicUid.iUid,EMPXCollectionCountTrack);
       
   285         if (iDbRecTotalCount == 0)
       
   286             {
       
   287             iSyncState = ESyncPlaylist;
       
   288             }
       
   289         }
       
   290     else
       
   291         {
       
   292         //get number of records from music table
       
   293         TInt count = CopyTableRecordsL(aTable,iMusicUid.iUid,EMPXCollectionURITrack);
       
   294         
       
   295         //continue with music or switch to playlist
       
   296         if(iCurDbRecCount >= iDbRecTotalCount || count == 0)
       
   297             {
       
   298             iDbRecTotalCount = 0;
       
   299             iCurDbRecCount = 0;
       
   300             iLastID = 0;
       
   301             iSyncState = ESyncPlaylist;
       
   302             }
       
   303         }
       
   304     }
       
   305 
       
   306 void CMPXDbSynchronizer::DoPlaylistTableSyncL(CMPXHarvesterDatabaseTable& aTable)
       
   307     {
       
   308     if(iDbRecTotalCount == 0)
       
   309         {
       
   310         //get total number of records from music db for playlist table
       
   311         GetTableCountL(iMusicUid.iUid,EMPXCollectionCountPlaylist);
       
   312         if (iDbRecTotalCount == 0)
       
   313             {
       
   314             iSyncState = ESyncPodcast;
       
   315             }
       
   316         }
       
   317     else
       
   318         {
       
   319         //get number of records from playlist table
       
   320         TInt count = CopyTableRecordsL(aTable,iMusicUid.iUid,EMPXCollectionURIPlaylist);
       
   321 
       
   322         //continue with music or switch to playlist
       
   323         if(iCurDbRecCount >= iDbRecTotalCount || count == 0)
       
   324             {
       
   325             iDbRecTotalCount = 0;
       
   326             iCurDbRecCount = 0;
       
   327             iLastID = 0;
       
   328             iSyncState = ESyncPodcast;
       
   329             }
       
   330         }
       
   331     }
       
   332 
       
   333 void CMPXDbSynchronizer::DoPodcastTableSyncL(CMPXHarvesterDatabaseTable& aTable)
       
   334     {
       
   335     if( iDisablePodcasting )
       
   336         {
       
   337         iDbDrives.Remove(0);
       
   338         iCurDrive = -1;
       
   339         iSyncState = ESyncMusic;
       
   340         }
       
   341     else
       
   342         {
       
   343         if(iDbRecTotalCount == 0)
       
   344             {
       
   345             //get total number of records from podcast db for podcast table
       
   346             GetTableCountL(iPodcastUid.iUid,EMPXCollectionCountTrack);
       
   347             if (iDbRecTotalCount == 0)
       
   348                 {
       
   349                 iDbDrives.Remove(0);
       
   350                 iCurDrive = -1;
       
   351                 iSyncState = ESyncMusic;
       
   352                 }
       
   353             }
       
   354         else
       
   355             {
       
   356             //get number of records from podcast table
       
   357             TInt count = CopyTableRecordsL(aTable,iPodcastUid.iUid,EMPXCollectionURITrack);
       
   358         
       
   359             //continue with music or switch to playlist
       
   360             if(iCurDbRecCount >= iDbRecTotalCount || count == 0)
       
   361                 {
       
   362                 iDbDrives.Remove(0);
       
   363                 iCurDrive = -1;
       
   364                 iSyncState = ESyncMusic;
       
   365                 }
       
   366             }
       
   367         }
       
   368     }
       
   369 
       
   370 void CMPXDbSynchronizer::CompleteSelf()
       
   371     {
       
   372     iStatus = KRequestPending;
       
   373     SetActive();
       
   374     TRequestStatus* status = &iStatus;
       
   375     User::RequestComplete( status, KErrNone );        
       
   376     }
       
   377 
       
   378 void CMPXDbSynchronizer::GetTableCountL(TInt aDbId, TInt aTable)
       
   379     {
       
   380     //get total number of records from given Db for a given table
       
   381     CMPXCommand* cmdCount = CMPXMedia::NewL();
       
   382     CleanupStack::PushL(cmdCount);
       
   383     cmdCount->SetTObjectValueL<TMPXCommandId>(KMPXCommandGeneralId, KMPXCommandCollectionGetCount);
       
   384     cmdCount->SetTObjectValueL<TBool>(KMPXCommandGeneralDoSync, ETrue);
       
   385     cmdCount->SetTObjectValueL<TInt>(KMPXCommandGeneralCollectionId, aDbId);
       
   386     cmdCount->SetTObjectValueL<TInt>(KMPXCommandCollectionCountTable, aTable);
       
   387     cmdCount->SetTObjectValueL<TInt>(KMPXCommandCollectionCountDrive, iCurDrive);
       
   388     
       
   389     iColUtil->Collection().CommandL(*cmdCount);
       
   390 
       
   391     // returned command should contain count
       
   392     if (!cmdCount->IsSupported(KMPXCommandCollectionCountValue))
       
   393         {
       
   394         User::Leave(KErrAbort);
       
   395         }
       
   396 
       
   397     iDbRecTotalCount = cmdCount->ValueTObjectL<TInt>(KMPXCommandCollectionCountValue);
       
   398     
       
   399     CleanupStack::PopAndDestroy(cmdCount);
       
   400     }
       
   401 
       
   402 TInt CMPXDbSynchronizer::CopyTableRecordsL(CMPXHarvesterDatabaseTable& aTable,
       
   403                                            TInt aColDbId, TInt aColTable)
       
   404     {
       
   405     //get number of records from given db and table
       
   406     CMPXCommand* cmdUri = CMPXMedia::NewL();
       
   407     CleanupStack::PushL(cmdUri);
       
   408     cmdUri->SetTObjectValueL<TMPXCommandId>(KMPXCommandGeneralId, KMPXCommandCollectionGetURIs);
       
   409     cmdUri->SetTObjectValueL<TBool>(KMPXCommandGeneralDoSync, ETrue);
       
   410     cmdUri->SetTObjectValueL<TInt>(KMPXCommandGeneralCollectionId, aColDbId);
       
   411     cmdUri->SetTObjectValueL<TInt>(KMPXCommandCollectionURIDrive, iCurDrive);
       
   412     cmdUri->SetTObjectValueL<TInt>(KMPXCommandCollectionURITable, aColTable);
       
   413     cmdUri->SetTObjectValueL<TInt>(KMPXCommandCollectionURIRecords, KRecStepCount); //number of records
       
   414     cmdUri->SetTObjectValueL<TInt>(KMPXCommandCollectionURIFromID, iLastID); //from last record
       
   415 
       
   416     // send sync retrieve count command
       
   417     iColUtil->Collection().CommandL(*cmdUri);
       
   418 
       
   419     // return command should contain Uri list and last item ID
       
   420     if (!cmdUri->IsSupported(KMPXCommandCollectionURIList) && 
       
   421         !cmdUri->IsSupported(KMPXCommandCollectionURILastID) )
       
   422         {
       
   423         User::Leave(KErrAbort);
       
   424         }
       
   425 
       
   426     //populate harvester db using received values;
       
   427     // retrieve the list of URIs
       
   428     CDesCArray* files = cmdUri->ValueNoNewLCObjectL<CDesCArray>(KMPXCommandCollectionURIList);
       
   429     CleanupStack::PushL(files);
       
   430 
       
   431     TInt uriCount = files->Count();
       
   432     for(TInt j=0; j<uriCount; ++j)
       
   433         {
       
   434         TTime lastModTime(0);
       
   435         TPtrC file((*files)[j]);
       
   436         //we need to add all files to harvester db to be able to remove non-existing later
       
   437         iFs.Modified(file, lastModTime);
       
   438         TParsePtrC parse(file);
       
   439         //if we leave here we it's ok to keep in harvester db what we managed to add
       
   440         aTable.AddItemL(parse.DriveAndPath(), parse.NameAndExt(),
       
   441                         lastModTime, aColDbId, 0); //drm is ok to be 0 here
       
   442         }
       
   443 
       
   444     iCurDbRecCount += uriCount;
       
   445     CleanupStack::PopAndDestroy(files);
       
   446     iLastID = cmdUri->ValueTObjectL<TInt>(KMPXCommandCollectionURILastID);
       
   447     CleanupStack::PopAndDestroy(cmdUri);
       
   448     
       
   449     return uriCount;
       
   450     }