diff -r 000000000000 -r ccd0fd43f247 harvesterplugins/file/src/cfileplugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/harvesterplugins/file/src/cfileplugin.cpp Mon Apr 19 14:40:05 2010 +0300 @@ -0,0 +1,486 @@ +/* +* Copyright (c) 2010 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: +* +*/ + + +#include +#include // PathInfo +#include // TDriveInfo +#include "cfileplugin.h" +#include "harvesterserverlogger.h" +#include "cfileharvester.h" +#include "cfileplugin.h" +#include "cfilemonitor.h" +#include "cmmcmonitor.h" +#include +#include +#include + +#include + +// local declarations and functions +namespace { + +_LIT(KCPixSearchServerPrivateDirectory, "\\Private\\2001f6f7\\"); +_LIT(KPathIndexDbPath, CPIX_INDEVICE_INDEXDB); + +_LIT(KPathTrailer, "\\root\\file"); +_LIT(KFileBaseAppClassGeneric, ":root file"); +_LIT(KFilePluginAtSign, "@"); +_LIT(KFilePluginColon, ":"); + +/** +* MapFileToDrive - returns the TDriveNumber that the file is located on. +* @aFilename filename +* @aDrive returns the TDriveNumber +* returns KErrNone on success or a standard error code +*/ +TInt MapFileToDrive(const TDesC& aFilename, TDriveNumber& aDrive) + { + TParse file; + file.Set(aFilename, NULL, NULL); + TPtrC drvChar = file.Drive().Left(1); + TChar d(drvChar[0]); + + TInt drive; + const TInt ret = RFs::CharToDrive(d, drive); + if (!ret) + { + aDrive = TDriveNumber(drive); + } + return ret; + } + +/** +* MapBaseAppClassToDrive - gets the TDriveNumber associated with the aBaseAppClass. +* @aBaseAppClass e.g. "@c:root file" +* @aDrive returns the TDriveNumber for the aBaseAppClass +* returns KErrNone on success or a standard error code +*/ +TInt MapBaseAppClassToDrive(const TDesC& aBaseAppClass, TDriveNumber& aDrive) + { + if (KErrNone != aBaseAppClass.Left(1).Compare(KFilePluginAtSign)) + { + return KErrGeneral; + } + + TPtrC drvChar = aBaseAppClass.Left(2).Right(1); + TChar d(drvChar[0]); + TInt drive; + const TInt ret = RFs::CharToDrive(d, drive); + if (!ret) + { + aDrive = TDriveNumber(drive); + } + + return ret; + } + +} // anonymous namespace + +CFilePlugin* CFilePlugin::NewL() + { + CFilePlugin* instance = CFilePlugin::NewLC(); + CleanupStack::Pop(instance); + return instance; + } + +CFilePlugin* CFilePlugin::NewLC() + { + CFilePlugin* instance = new (ELeave)CFilePlugin(); + CleanupStack::PushL(instance); + instance->ConstructL(); + return instance; + } + +CFilePlugin::CFilePlugin() + { + for (TInt i=EDriveA; i<=EDriveZ; i++) + { + iIndexer[i] = NULL; //Initialize to NULL + } + } + +CFilePlugin::~CFilePlugin() + { + CPIXLOGSTRING("CFilePlugin::~CFilePlugin()"); + + // remove notification paths before destroying iMonitor + for (TInt i=EDriveA; i<=EDriveZ; i++) + { + UnMount(TDriveNumber(i), EFalse); + } + delete iHarvester; + delete iMonitor; + delete iMmcMonitor; + + TInt err = iFs.DismountPlugin(KFastFindFSPluginName); + CPIXLOGSTRING2("CFilePlugin::~CFilePlugin(), iFs.DismountPlugin: %i", err); + err = iFs.RemovePlugin(KFastFindFSPluginName); + CPIXLOGSTRING2("CFilePlugin::~CFilePlugin(), iFs.RemovePlugin: %i", err); + iFs.Close(); + } + +void CFilePlugin::ConstructL() + { + User::LeaveIfError( iFs.Connect() ); + TInt err = iFs.AddPlugin(KFastFindFSPluginFile); + CPIXLOGSTRING2("CFilePlugin::ConstructL, iFs.AddPlugin: %i", err); + if ( err != KErrAlreadyExists ) + { + err = iFs.MountPlugin(KFastFindFSPluginName); + CPIXLOGSTRING2("CFilePlugin::ConstructL, iFs.MountPlugin: %i", err); + } + // check if already up, unload and reload + else if ( err == KErrAlreadyExists ) + { + // dismount + TInt err = iFs.DismountPlugin(KFastFindFSPluginName); + CPIXLOGSTRING2("CFilePlugin::ConstructL(), iFs.DismountPlugin: %i", err); + err = iFs.RemovePlugin(KFastFindFSPluginName); + CPIXLOGSTRING2("CFilePlugin::ConstructL(), iFs.RemovePlugin: %i", err); + // if no error reload + if ( err == KErrNone ) + { + err = iFs.AddPlugin(KFastFindFSPluginFile); + CPIXLOGSTRING2("CFilePlugin::ConstructL, iFs.AddPlugin: %i", err); + err = iFs.MountPlugin(KFastFindFSPluginName); + CPIXLOGSTRING2("CFilePlugin::ConstructL, iFs.MountPlugin: %i", err); + } + } + + iHarvester = CFileHarvester::NewL(*this, iFs); + iMonitor = CFileMonitor::NewL(*this, &iFs); + iMmcMonitor = CMMCMonitor::NewL(*this, &iFs); + } + +void CFilePlugin::StartPluginL() + { + TInt error = KErrNone; + + if (!iIsMonitorInit) + { + error = iMonitor->Initialize(); + CPIXLOGSTRING2("CFilePlugin::StartMonitoring, error: %i", error ); + iIsMonitorInit = ETrue; + } + + // Start the monitoring + if (error == KErrNone && iIsMonitorInit) + { + iMonitor->StartMonitoring(); + CPIXLOGSTRING("CFilePlugin::StartMonitoring - iFileMonitor->StartMonitoring "); + } + + iMmcMonitor->StartMonitoring(); + + CPIXLOGSTRING("END CFilePlugin::StartMonitoring"); + + // Add harvesters for each non removable drive + for ( TInt driveNumber = EDriveA; driveNumber <= EDriveZ; driveNumber++ ) + { + if ( iFs.IsValidDrive( driveNumber ) ) + { + TUint drvStatus( 0 ); + TInt err = DriveInfo::GetDriveStatus(iFs, TDriveNumber(driveNumber), drvStatus); + if ( err != KErrNone ) + { + continue; + } + + // Harvest drive that are internal, non-removable, user visible, present + if ( ( drvStatus & DriveInfo::EDriveInternal ) && + !( drvStatus & DriveInfo::EDriveRemovable ) && // NOT removable + ( drvStatus & DriveInfo::EDriveUserVisible ) && + ( drvStatus & DriveInfo::EDrivePresent ) ) + { + MountL(TDriveNumber(driveNumber)); + } + } + } +} + +void CFilePlugin::MountL(TDriveNumber aMedia, TBool aForceReharvest) + { + CPIXLOGSTRING("ENTER CFilePlugin::MountL"); + // Check if already exists + if (iIndexer[aMedia]) + return; + + // Add Notifications paths prior to opening IndexDB. + AddNotificationPathsL(aMedia); + + // Form the baseappclass for this media + TBuf baseAppClass; + FormBaseAppClass(aMedia, baseAppClass); + + // Define this volume + HBufC* path = DatabasePathLC(aMedia); + User::LeaveIfError(iSearchSession.DefineVolume(baseAppClass, *path)); + CleanupStack::PopAndDestroy(path); + + // construct and open the database + iIndexer[aMedia] = CCPixIndexer::NewL(iSearchSession); + iIndexer[aMedia]->OpenDatabaseL(baseAppClass); + + // Add to harvesting queue + iObserver->AddHarvestingQueue(this, baseAppClass, aForceReharvest); + CPIXLOGSTRING("END CFilePlugin::MountL"); + } + +void CFilePlugin::UnMount(TDriveNumber aMedia, TBool aUndefineAsWell) + { + CPIXLOGSTRING("ENTER CFilePlugin::UnMount "); + // Check if already exists + if (!iIndexer[aMedia]) + { + return; + } + + // Form the baseappclass for this media + TBuf baseAppClass; + FormBaseAppClass(aMedia, baseAppClass); + + // Remove from harvesting queue + iObserver->RemoveHarvestingQueue(this, baseAppClass); + + // Delete the index object + if (iIndexer[aMedia]) + { + delete iIndexer[aMedia]; + iIndexer[aMedia] = NULL; + } + + RemoveNotificationPaths(aMedia); + + if (aUndefineAsWell) + { + iSearchSession.UnDefineVolume(baseAppClass); + } + CPIXLOGSTRING("END CFilePlugin::UnMount "); + } + +void CFilePlugin::StartHarvestingL(const TDesC& aQualifiedBaseAppClass) + { + CPIXLOGSTRING("ENTER CFilePlugin::StartHarvestingL "); + // Map base app class to a drive number + TDriveNumber drive(EDriveA); //Initialize to get rid of compiler warning. + if (KErrNone != MapBaseAppClassToDrive(aQualifiedBaseAppClass, drive)) + { + User::Leave(KErrGeneral); + } + + // Leave if no indexer for this drive + if (!iIndexer[drive]) + { + User::Leave(KErrGeneral); + } + +#ifdef __PERFORMANCE_DATA + iStartTime[drive].UniversalTime(); +#endif + // Reset the database + iIndexer[drive]->ResetL(); + + // Start the actual harvest + iHarvester->StartL(drive); + CPIXLOGSTRING("END CFilePlugin::StartHarvestingL "); + } + +void CFilePlugin::CreateFileIndexItemL(const TDesC& aFilename, TCPixActionType aActionType) + { + TFileName lowerCaseFilename(aFilename); + lowerCaseFilename.LowerCase(); + + CPIXLOGSTRING3("CFilePlugin::CreateFileIndexItemL lowerCaseFilename = %S aActionType = %d ", + &lowerCaseFilename, aActionType); + + TDriveNumber drive(EDriveA); + User::LeaveIfError( MapFileToDrive( lowerCaseFilename, drive ) ); + + CCPixIndexer* indexer = iIndexer[drive]; + if (!indexer) + { + CPIXLOGSTRING("CFilePlugin::CreateFileIndexItemL(): Could not map file to drive."); + return; + } + + // Index an empty item if removal action + if (aActionType == ECPixRemoveAction) + { +#ifdef _DEBUG + TRAPD(err, indexer->DeleteL(lowerCaseFilename)); + CPIXLOGSTRING2("CFilePlugin::CreateFileIndexItemL(): DeleteL returned %d.", err); +#else + TRAP_IGNORE( indexer->DeleteL(lowerCaseFilename) ); +#endif + } + else + { + // creating CSearchDocument object with unique ID for this application + CSearchDocument* index_item = CSearchDocument::NewLC(lowerCaseFilename, KNullDesC, KNullDesC, CSearchDocument::EFileParser); + + // Send for indexing + if (aActionType == ECPixAddAction) + { +#ifdef _DEBUG + TRAPD(err, indexer->AddL(*index_item)); + CPIXLOGSTRING2("CFilePlugin::CreateFileIndexItemL(): AddL returned %d.", err); +#else + TRAP_IGNORE( indexer->AddL(*index_item) ); +#endif + } + else if (aActionType == ECPixUpdateAction) + { +#ifdef _DEBUG + TRAPD(err, indexer->UpdateL(*index_item)); + CPIXLOGSTRING2("CFilePlugin::CreateFileIndexItemL(): UpdateL returned %d.", err); +#else + TRAP_IGNORE( indexer->UpdateL(*index_item) ); +#endif + } + CleanupStack::PopAndDestroy(index_item); + } + } + +void CFilePlugin::HarvestingCompleted(TDriveNumber aDriveNumber, TInt aError) + { + CPIXLOGSTRING("ENTER CFilePlugin::HarvestingCompleted "); + + if (iIndexer[aDriveNumber]) + { + Flush(*iIndexer[aDriveNumber]); + } + TBuf baseAppClass; + FormBaseAppClass(TDriveNumber(aDriveNumber), baseAppClass); +#ifdef __PERFORMANCE_DATA + TRAP_IGNORE( UpdatePerformaceDataL(aDriveNumber) ); +#endif + iObserver->HarvestingCompleted(this, baseAppClass, aError); + + CPIXLOGSTRING("END CFilePlugin::HarvestingCompleted "); + } + +void CFilePlugin::AddNotificationPathsL(const TDriveNumber aDriveNumber) + { + CPIXLOGSTRING("ENTER CFilePlugin::AddNotificationPathsL "); + iMonitor->AddNotificationPathsL(aDriveNumber); + iHarvester->AddIgnorePathsL(aDriveNumber); + CPIXLOGSTRING("END CFilePlugin::AddNotificationPathsL "); + } + +void CFilePlugin::RemoveNotificationPaths(const TDriveNumber aDriveNumber) + { + CPIXLOGSTRING("ENTER CFilePlugin::RemoveNotificationPaths"); + iMonitor->RemoveNotificationPaths(aDriveNumber); + iHarvester->RemoveIgnorePaths(aDriveNumber); + CPIXLOGSTRING("END CFilePlugin::RemoveNotificationPaths"); + } + +TInt CFilePlugin::FormBaseAppClass(TDriveNumber aMedia, TDes& aBaseAppClass) + { + CPIXLOGSTRING("ENTER CFilePlugin::FormBaseAppClass"); + TChar chr; + const TInt ret = RFs::DriveToChar(aMedia, chr); + if (KErrNone == ret) + { + aBaseAppClass.Copy(KFilePluginAtSign); + aBaseAppClass.Append(chr); + aBaseAppClass.LowerCase(); + aBaseAppClass.Append(KFileBaseAppClassGeneric); + } + + CPIXLOGSTRING("END CFilePlugin::FormBaseAppClass"); + return ret; + } + +HBufC* CFilePlugin::DatabasePathLC(TDriveNumber aMedia) + { + CPIXLOGSTRING("ENTER CFilePlugin::DatabasePathLC"); + // Allocate extra space for root path e.g. "C:\\Private\\2001f6f7\\" + const TInt KRootPathMaxLength = 30; + HBufC* indexDbPath = HBufC::NewLC(KRootPathMaxLength + KPathIndexDbPath().Length() + KPathTrailer().Length()); + TPtr indexDbPathPtr = indexDbPath->Des(); + + // Data caging implementation + iFs.CreatePrivatePath(aMedia); + + TChar chr; + RFs::DriveToChar(aMedia, chr); + indexDbPathPtr.Append(chr); + indexDbPathPtr.Append(KFilePluginColon); + + TFileName pathWithoutDrive; + iFs.PrivatePath(pathWithoutDrive); + indexDbPathPtr.Append(KCPixSearchServerPrivateDirectory); + + indexDbPathPtr.Append(KPathIndexDbPath); + indexDbPathPtr.Append(KPathTrailer); + + CPIXLOGSTRING("END CFilePlugin::DatabasePathLC"); + return indexDbPath; + } + +#ifdef __PERFORMANCE_DATA +void CFilePlugin::UpdatePerformaceDataL(TDriveNumber aDriveNumber) + { + TTime now; + TChar aChar; + + iCompleteTime.UniversalTime(); + TTimeIntervalMicroSeconds timeDiff = iCompleteTime.MicroSecondsFrom(iStartTime[aDriveNumber]); + + RFs fileSession; + RFile perfFile; + User::LeaveIfError( fileSession.Connect () ); + RFs::DriveToChar((TInt)aDriveNumber, aChar); + + + /* Open file if it exists, otherwise create it and write content in it */ + + if(perfFile.Open(fileSession, _L("c:\\data\\FilePerf.txt"), EFileWrite)) + User::LeaveIfError(perfFile.Create (fileSession, _L("c:\\data\\FilePerf.txt"), EFileWrite)); + + HBufC8 *heap = HBufC8::NewL(100); + TPtr8 ptr = heap->Des(); + now.HomeTime(); + TBuf<50> timeString; + + _LIT(KOwnTimeFormat,"%:0%H%:1%T%:2%S"); + now.FormatL(timeString,KOwnTimeFormat); + ptr.AppendNum(now.DateTime().Day()); + ptr.Append(_L("/")); + ptr.AppendNum(now.DateTime().Month()); + ptr.Append(_L("/")); + ptr.AppendNum(now.DateTime().Year()); + ptr.Append(_L(":")); + ptr.Append(timeString); + ptr.Append(_L("Drive ")); + ptr.Append(aChar); + ptr.Append( _L(" Ani: Time took for Harvesting File is : ")); + ptr.AppendNum(timeDiff.Int64()/1000) ; + ptr.Append(_L(" MilliSeonds \n")); + TInt myInt = 0; + perfFile.Seek(ESeekEnd,myInt); + perfFile.Write (ptr); + perfFile.Close (); + fileSession.Close (); + delete heap; + } +#endif + +// End of file +