diff -r 000000000000 -r a2952bb97e68 mmappcomponents/harvester/filehandler/src/mpxdbsynchronizer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmappcomponents/harvester/filehandler/src/mpxdbsynchronizer.cpp Thu Dec 17 08:55:47 2009 +0200 @@ -0,0 +1,450 @@ +/* +* Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Class for synchronization collection and harvester databases +* +*/ + +#include +#include +#include +#include +#include + +#include "mpxcommand.h" +#include "mpxharvesterdbmanager.h" +#include "mpxharvesterdbtable.h" +#include "mpxdbsynchronizer.h" +#include "mpxdbsyncobserver.h" + +#include +#include // to get podcasting cenrep key +// CONSTANTS +const TInt KRecStepCount = 100; + +// ======== LOCAL FUNCTIONS ======== + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// +CMPXDbSynchronizer::CMPXDbSynchronizer(MMPXDbSyncObserver& aObserver, + CMPXHarvesterDatabaseManager& aDbMng, + const TUid& aMusic, + const TUid& aPodcast, + RFs& aFs, + TBool aDisablePodcast ) + : CActive(EPriorityNull), //using the same priority as folder scanner + iSyncObserver(aObserver), + iDBManager(aDbMng), + iColUtil(NULL), + iMusicUid(aMusic), + iPodcastUid(aPodcast), + iFs(aFs), + iSyncState(ESyncStopped), + iCurDrive(-1), + iDbRecTotalCount(0), + iCurDbRecCount(0), + iLastID(0), + iDisablePodcasting( aDisablePodcast ) + { + CActiveScheduler::Add(this); + } + +// --------------------------------------------------------------------------- +// 2nd Phase Constructor +// --------------------------------------------------------------------------- +// +void CMPXDbSynchronizer::ConstructL() + { + } + +// --------------------------------------------------------------------------- +// Two Phased Constructor +// --------------------------------------------------------------------------- +// +CMPXDbSynchronizer* CMPXDbSynchronizer::NewL(MMPXDbSyncObserver& aObserver, + CMPXHarvesterDatabaseManager& aDbMng, + const TUid& aMusic, + const TUid& aPodcast, + RFs& aFs, + TBool aDisablePodcast ) + { + CMPXDbSynchronizer* self = new(ELeave) CMPXDbSynchronizer(aObserver,aDbMng,aMusic, + aPodcast,aFs,aDisablePodcast); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +// +CMPXDbSynchronizer::~CMPXDbSynchronizer() + { + Cancel(); + iDbDrives.Close(); + } + +// --------------------------------------------------------------------------- +// Scans a list of drives for files +// --------------------------------------------------------------------------- +// +void CMPXDbSynchronizer::Synchronize(RArray& aDrives, MMPXCollectionUtility* aColUtil) + { + MPX_DEBUG1("---> CMPXDbSynchronizer::Synchronize"); + ASSERT(aColUtil != NULL); //internal call, should be always ok + + iColUtil = aColUtil; + + //check if synchronization is already active then ignore request + if(iSyncState == ESyncStopped) + { + TInt dbCount(iDBManager.Count()); + TInt count(aDrives.Count()); + + if(dbCount >= count && count != 0) + { + for(TInt i=0; i CMPXDbSynchronizer::DoSynchronizeStepL"); + + TBool ret(EFalse); + + if(iDbDrives.Count() != 0) + { + TBool clear(EFalse); + //first time for a database on this drive + if(iCurDrive == -1) + { + iCurDrive = iDbDrives[0]; + clear = ETrue; + } + + CMPXHarvesterDB& db = iDBManager.GetDatabaseL((TDriveNumber)iCurDrive); + CMPXHarvesterDatabaseTable* table = db.OpenAllFilesTableL(); + CleanupStack::PushL(table); + + if(clear) + { + db.RemoveAllFilesL(); + iDbRecTotalCount = 0; + iCurDbRecCount = 0; + iLastID = 0; + } + + switch(iSyncState) + { + case ESyncMusic: //now getting music table content from curr drive's db + { + DoMusicTableSyncL(*table); + break; + } + case ESyncPlaylist: //now getting playlist table content (music db) + { + DoPlaylistTableSyncL(*table); + break; + } + case ESyncPodcast: //now getting podcast table content (podcast db) + { + DoPodcastTableSyncL(*table); + break; + } + default: + { + User::Leave(KErrAbort); + } + } + + CleanupStack::PopAndDestroy(table); + } + else + { + ret = ETrue; //sync complete + } + + MPX_DEBUG1("<--- CMPXDbSynchronizer::SetupNextDriveToScanL return"); + return ret; + } + +// --------------------------------------------------------------------------- +// Handle when synchronization is complete +// --------------------------------------------------------------------------- +// +void CMPXDbSynchronizer::DoSynchronizeComplete(TInt aErr) + { + MPX_DEBUG1("---> CMPXDbSynchronizer::DoSynchronizeComplete"); + + iDbDrives.Reset(); // Reset drives + iSyncState = ESyncStopped; + + iCurDrive = -1; + iDbRecTotalCount = 0; + iCurDbRecCount = 0; + + // Notify observer + iSyncObserver.HandleSynchronizationComplete(aErr); + + MPX_DEBUG1("<--- CMPXDbSynchronizer::DoSynchronizeComplete"); + } + +// --------------------------------------------------------------------------- +// From CActive +// --------------------------------------------------------------------------- +// +void CMPXDbSynchronizer::RunL() + { + MPX_DEBUG1("---> CMPXDbSynchronizer::RunL"); + + TBool done(EFalse); + done = DoSynchronizeStepL(); + + if(done) + { + DoSynchronizeComplete(KErrNone); + } + else // if( !done ) + { + MPX_DEBUG1("CMPXDbSynchronizer::RunL -- Schedule next run"); + CompleteSelf(); + } + MPX_DEBUG1("<--- CMPXDbSynchronizer::RunL"); + } + +// --------------------------------------------------------------------------- +// From CActive +// --------------------------------------------------------------------------- +// +void CMPXDbSynchronizer::DoCancel() + { + ASSERT(iSyncState != ESyncStopped); + DoSynchronizeComplete(KErrCancel); + } + +// ---------------------------------------------------------------------------- +// Handles a leave occurring in the request completion event handler RunL() +// ---------------------------------------------------------------------------- +// +TInt CMPXDbSynchronizer::RunError(TInt aError) + { + MPX_DEBUG2("CMPXDbSynchronizer::RunError(%d)", aError ); + + DoSynchronizeComplete(aError); + + return KErrNone; + } + +//Helper functions implementation +void CMPXDbSynchronizer::DoMusicTableSyncL(CMPXHarvesterDatabaseTable& aTable) + { + if(iDbRecTotalCount == 0) + { + //get total number of records from music db for music table + GetTableCountL(iMusicUid.iUid,EMPXCollectionCountTrack); + if (iDbRecTotalCount == 0) + { + iSyncState = ESyncPlaylist; + } + } + else + { + //get number of records from music table + TInt count = CopyTableRecordsL(aTable,iMusicUid.iUid,EMPXCollectionURITrack); + + //continue with music or switch to playlist + if(iCurDbRecCount >= iDbRecTotalCount || count == 0) + { + iDbRecTotalCount = 0; + iCurDbRecCount = 0; + iLastID = 0; + iSyncState = ESyncPlaylist; + } + } + } + +void CMPXDbSynchronizer::DoPlaylistTableSyncL(CMPXHarvesterDatabaseTable& aTable) + { + if(iDbRecTotalCount == 0) + { + //get total number of records from music db for playlist table + GetTableCountL(iMusicUid.iUid,EMPXCollectionCountPlaylist); + if (iDbRecTotalCount == 0) + { + iSyncState = ESyncPodcast; + } + } + else + { + //get number of records from playlist table + TInt count = CopyTableRecordsL(aTable,iMusicUid.iUid,EMPXCollectionURIPlaylist); + + //continue with music or switch to playlist + if(iCurDbRecCount >= iDbRecTotalCount || count == 0) + { + iDbRecTotalCount = 0; + iCurDbRecCount = 0; + iLastID = 0; + iSyncState = ESyncPodcast; + } + } + } + +void CMPXDbSynchronizer::DoPodcastTableSyncL(CMPXHarvesterDatabaseTable& aTable) + { + if( iDisablePodcasting ) + { + iDbDrives.Remove(0); + iCurDrive = -1; + iSyncState = ESyncMusic; + } + else + { + if(iDbRecTotalCount == 0) + { + //get total number of records from podcast db for podcast table + GetTableCountL(iPodcastUid.iUid,EMPXCollectionCountTrack); + if (iDbRecTotalCount == 0) + { + iDbDrives.Remove(0); + iCurDrive = -1; + iSyncState = ESyncMusic; + } + } + else + { + //get number of records from podcast table + TInt count = CopyTableRecordsL(aTable,iPodcastUid.iUid,EMPXCollectionURITrack); + + //continue with music or switch to playlist + if(iCurDbRecCount >= iDbRecTotalCount || count == 0) + { + iDbDrives.Remove(0); + iCurDrive = -1; + iSyncState = ESyncMusic; + } + } + } + } + +void CMPXDbSynchronizer::CompleteSelf() + { + iStatus = KRequestPending; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + } + +void CMPXDbSynchronizer::GetTableCountL(TInt aDbId, TInt aTable) + { + //get total number of records from given Db for a given table + CMPXCommand* cmdCount = CMPXMedia::NewL(); + CleanupStack::PushL(cmdCount); + cmdCount->SetTObjectValueL(KMPXCommandGeneralId, KMPXCommandCollectionGetCount); + cmdCount->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue); + cmdCount->SetTObjectValueL(KMPXCommandGeneralCollectionId, aDbId); + cmdCount->SetTObjectValueL(KMPXCommandCollectionCountTable, aTable); + cmdCount->SetTObjectValueL(KMPXCommandCollectionCountDrive, iCurDrive); + + iColUtil->Collection().CommandL(*cmdCount); + + // returned command should contain count + if (!cmdCount->IsSupported(KMPXCommandCollectionCountValue)) + { + User::Leave(KErrAbort); + } + + iDbRecTotalCount = cmdCount->ValueTObjectL(KMPXCommandCollectionCountValue); + + CleanupStack::PopAndDestroy(cmdCount); + } + +TInt CMPXDbSynchronizer::CopyTableRecordsL(CMPXHarvesterDatabaseTable& aTable, + TInt aColDbId, TInt aColTable) + { + //get number of records from given db and table + CMPXCommand* cmdUri = CMPXMedia::NewL(); + CleanupStack::PushL(cmdUri); + cmdUri->SetTObjectValueL(KMPXCommandGeneralId, KMPXCommandCollectionGetURIs); + cmdUri->SetTObjectValueL(KMPXCommandGeneralDoSync, ETrue); + cmdUri->SetTObjectValueL(KMPXCommandGeneralCollectionId, aColDbId); + cmdUri->SetTObjectValueL(KMPXCommandCollectionURIDrive, iCurDrive); + cmdUri->SetTObjectValueL(KMPXCommandCollectionURITable, aColTable); + cmdUri->SetTObjectValueL(KMPXCommandCollectionURIRecords, KRecStepCount); //number of records + cmdUri->SetTObjectValueL(KMPXCommandCollectionURIFromID, iLastID); //from last record + + // send sync retrieve count command + iColUtil->Collection().CommandL(*cmdUri); + + // return command should contain Uri list and last item ID + if (!cmdUri->IsSupported(KMPXCommandCollectionURIList) && + !cmdUri->IsSupported(KMPXCommandCollectionURILastID) ) + { + User::Leave(KErrAbort); + } + + //populate harvester db using received values; + // retrieve the list of URIs + CDesCArray* files = cmdUri->ValueNoNewLCObjectL(KMPXCommandCollectionURIList); + CleanupStack::PushL(files); + + TInt uriCount = files->Count(); + for(TInt j=0; jValueTObjectL(KMPXCommandCollectionURILastID); + CleanupStack::PopAndDestroy(cmdUri); + + return uriCount; + }