diff -r 000000000000 -r ccd0fd43f247 harvesterplugins/file/src/cfilemonitor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/harvesterplugins/file/src/cfilemonitor.cpp Mon Apr 19 14:40:05 2010 +0300 @@ -0,0 +1,384 @@ +/* +* 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 FILES +#include + +#include "cfilemonitor.h" +#include "cfolderrenamedharvester.h" +#include "harvesterserverlogger.h" + +// ----------------------------------------------------------------------------- +// CFileMonitor::NewL +// ----------------------------------------------------------------------------- +// +CFileMonitor* CFileMonitor::NewL( CFilePlugin& aFilePlugin, RFs* aFsSession ) + { + CFileMonitor* self = new ( ELeave ) CFileMonitor( aFilePlugin, aFsSession ); + CleanupStack::PushL(self); + self->ConstructL(aFilePlugin, aFsSession); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::CFileMonitor +// ----------------------------------------------------------------------------- +// +CFileMonitor::CFileMonitor( CFilePlugin& aFilePlugin, RFs* aFsSession ) : + CActive(CActive::EPriorityStandard), + iFilePlugin( aFilePlugin ) + { + CPIXLOGSTRING("ENTER CFileMonitor::CFileMonitor"); + CActiveScheduler::Add(this); + iFsSession = aFsSession; + CPIXLOGSTRING("END CFileMonitor::CFileMonitor"); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::~CFileMonitor +// ----------------------------------------------------------------------------- +// +CFileMonitor::~CFileMonitor() + { + CPIXLOGSTRING("ENTER ~CFileMonitor"); + Cancel(); + iEngine.Disable(); + iEngine.Close(); + delete iFolderRenamedHarvester; + CPIXLOGSTRING("END ~CFileMonitor"); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::ConstructL +// ----------------------------------------------------------------------------- +// +void CFileMonitor::ConstructL( CFilePlugin& aFilePlugin, RFs* aFsSession ) + { + iFolderRenamedHarvester = CFolderRenamedHarvester::NewL(aFilePlugin, *aFsSession); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::RunError +// ----------------------------------------------------------------------------- +// +TInt CFileMonitor::RunError( TInt aError ) + { + CPIXLOGSTRING2( "CFileMonitor::RunError %d", aError ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::DoCancel +// ----------------------------------------------------------------------------- +// +void CFileMonitor::DoCancel() + { + iEngine.NotificationCancel(); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::RunL +// ----------------------------------------------------------------------------- +// +void CFileMonitor::RunL() + { + CPIXLOGSTRING("ENTER CFileMonitor::RunL"); + Deque(); + CActiveScheduler::Add( this ); + + /* + Handle pkg here + It has event type and other stuff + Execute event and pass params to FilePlugin + */ + + // TODO TFileName on stack twice - consider allocating on heap! + TFastFindFSPStatus& status = iPckg(); + const TDesC& fileNameOld = status.iFileName; + const TDesC& fileNameNew = status.iNewFileName; + + /* + * IMPORTANT: + * Rename of whole directory happens as change to every file in dir. + * We get an event of every file in dir. + */ + CPIXLOGSTRING2("CFileMonitor::RunL, status.iFileEventType: %i", status.iFileEventType ); + switch(status.iFileEventType) + { + case EFastFindFileCreated: + { + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileCreated old = %S", &fileNameOld); + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileCreated new = %S", &fileNameNew); + // File creation (for example over PC suite) gives fileNameOld as the created files, fileNameOld is empty. + iFilePlugin.CreateFileIndexItemL(fileNameOld, ECPixAddAction); + } + break; + + case EFastFindFileModified: + { + // This event can be generated by some file manager applications + // when copying a file to a new destination. + // Introduce a small delay, so that file copying can complete before + // cpix opens the file for indexing. Without the delay, sometimes file + // indexing fails as CLucene cannot open the file for indexing. + + // Decided to block the CPiXHarvesterServer thread rather than introduce + // new active object state into the CFileMonitor. + User::After(50000); // 0.05 seconds + + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileModified old = %S", &fileNameOld); + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileModified new = %S", &fileNameNew); + // File copy, fileNameOld contains the file name, fileNameNew is empty + iFilePlugin.CreateFileIndexItemL(fileNameOld, ECPixUpdateAction); + } + break; + + case EFastFindFileRenamed: + { + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileRenamed old = %S", &fileNameOld); + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileRenamed new = %S", &fileNameNew); + TEntry entry; + if ( iFsSession->Entry( fileNameNew, entry ) == KErrNone ) + { + if ( !entry.IsDir() ) + { + if (fileNameOld.Length()>0 && fileNameOld.Compare(fileNameNew)!=0) + { + iFilePlugin.CreateFileIndexItemL(fileNameOld, ECPixRemoveAction); + } + iFilePlugin.CreateFileIndexItemL(fileNameNew, ECPixUpdateAction); + } + else + { + iFolderRenamedHarvester->StartL(fileNameOld, fileNameNew); + } + } + } + break; + + case EFastFindFileReplaced: + { + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileReplaced old = %S", &fileNameOld); + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileReplaced new = %S", &fileNameNew); + // File rename (funnily), fileNameOld contains the old file name, fileNameNew the new name + if (fileNameOld.Length()>0 && fileNameOld.Compare(fileNameNew)!=0) + iFilePlugin.CreateFileIndexItemL(fileNameOld, ECPixRemoveAction); + iFilePlugin.CreateFileIndexItemL(fileNameNew, ECPixUpdateAction); + } + break; + + case EFastFindFileDeleted: + { + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileDeleted old = %S", &fileNameOld); + CPIXLOGSTRING2("CFileMonitor::RunL, EFastFindFileDeleted new = %S", &fileNameNew); + // File delete, fileNameOld contains the name of the deleted file + iFilePlugin.CreateFileIndexItemL(fileNameOld, ECPixRemoveAction); + } + break; + + default: + { + CPIXLOGSTRING2("CFileMonitor::RunL, unknown event old = %S", &fileNameOld); + CPIXLOGSTRING2("CFileMonitor::RunL, unknown event new = %S", &fileNameNew); + } + break; + } + ResetStatus(); + iEngine.RegisterNotification(iPckg, iStatus); + CPIXLOGSTRING("END CFileMonitor::RunL"); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::StartMonitoring +// ----------------------------------------------------------------------------- +// +TBool CFileMonitor::StartMonitoring() + { + CPIXLOGSTRING("ENTER CFileMonitor::StartMonitoring") + + if ( !IsActive() ) + { + CPIXLOGSTRING("CFileMonitor::StartMonitoring - IF ") + iEngine.Enable(); + ResetStatus(); + iEngine.RegisterNotification( iPckg, iStatus ); + SetActive(); + } + + CPIXLOGSTRING("END CFileMonitor::StartMonitoring"); + + return ETrue; + } + +// --------------------------------------------------------------------------- +// CFileMonitor::ResetStatus +// --------------------------------------------------------------------------- +// +void CFileMonitor::ResetStatus() + { + CPIXLOGSTRING( "CFileMonitor::ResetStatus" ); + + TFastFindFSPStatus& status = iPckg(); + + status.iDriveNumber = 0; + status.iFileEventType = EFastFindFileUnknown; + status.iFileName.Zero(); + status.iNewFileName.Zero(); + status.iProcessId = TUid::Null(); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::Initialize +// ----------------------------------------------------------------------------- +// +TInt CFileMonitor::Initialize() + { + CPIXLOGSTRING("ENTER CFileMonitor::Initialize"); + TInt err = OpenEngine(); + CPIXLOGSTRING2("CFileMonitor::Initialize - OpenEngine: %i", err ); + if ( err != KErrNone ) + { + CPIXLOGSTRING("CFileMonitor::Initialize if( err != KErrNone ) "); + return err; + } + + CPIXLOGSTRING("END CFileMonitor::Initialize"); + return err; + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::Release +// ----------------------------------------------------------------------------- +// +TInt CFileMonitor::Release() + { + iEngine.Disable(); + iEngine.Close(); + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::OpenEngine +// ----------------------------------------------------------------------------- +// +TInt CFileMonitor::OpenEngine() + { + TInt err = iEngine.Open( *iFsSession, KFastFindFSPluginPosition ); + return err; + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::AddNotificationPathsL +// ----------------------------------------------------------------------------- +// +void CFileMonitor::AddNotificationPathsL( const TDriveNumber aDriveNumber ) + { + TFileName notificationPath; + TChar chr; + User::LeaveIfError( RFs::DriveToChar( aDriveNumber, chr ) ); + + notificationPath.Append( chr ); + notificationPath.Append( KExcludePathSystem ); + iEngine.AddIgnorePath( notificationPath ); + CPIXLOGSTRING2("CFileMonitor::AddNotificationPathsL - AddIgnorePath: %S", ¬ificationPath ); + + notificationPath.Zero(); + + // As index databases are located under \\Private\\ path, + // this ignore path will mean index databases are also ignored. + notificationPath.Append( chr ); + notificationPath.Append( KExcludePathPrivate ); + iEngine.AddIgnorePath( notificationPath ); + CPIXLOGSTRING2("CFileMonitor::AddNotificationPathsL - AddIgnorePath: %S", ¬ificationPath ); + + notificationPath.Zero(); + + // Maps data must not be indexed + notificationPath.Append( chr ); + notificationPath.Append( KExcludePathMapsCities ); + iEngine.AddIgnorePath( notificationPath ); + CPIXLOGSTRING2("CFileMonitor::AddNotificationPathsL - AddIgnorePath: %S", ¬ificationPath ); + + notificationPath.Zero(); + + User::LeaveIfError( PathInfo::GetRootPath( notificationPath, aDriveNumber ) ); + iEngine.AddNotificationPath( notificationPath ); + CPIXLOGSTRING2("CFileMonitor::AddNotificationPathsL - AddNotificationPath: %S", ¬ificationPath ); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::RemoveNotificationPaths +// ----------------------------------------------------------------------------- +// +void CFileMonitor::RemoveNotificationPaths( const TDriveNumber aDriveNumber ) + { + TFileName ignorePath; + TChar chr; + RFs::DriveToChar( aDriveNumber, chr ); + + ignorePath.Append( chr ); + ignorePath.Append( KExcludePathSystem ); + iEngine.RemoveIgnorePath( ignorePath ); + CPIXLOGSTRING2("CFileMonitor::RemoveNotificationPaths - RemoveIgnorePath: %S", &ignorePath ); + + ignorePath.Zero(); + + // As index databases are located under \\Private\\ path, + // this ignore path will mean index databases are also ignored. + ignorePath.Append( chr ); + ignorePath.Append( KExcludePathPrivate ); + iEngine.RemoveIgnorePath( ignorePath ); + CPIXLOGSTRING2("CFileMonitor::RemoveNotificationPaths - RemoveIgnorePath: %S", &ignorePath ); + + ignorePath.Zero(); + + // Maps + ignorePath.Append( chr ); + ignorePath.Append( KExcludePathMapsCities ); + iEngine.RemoveIgnorePath( ignorePath ); + CPIXLOGSTRING2("CFileMonitor::RemoveNotificationPaths - RemoveIgnorePath: %S", &ignorePath ); + + ignorePath.Zero(); + + PathInfo::GetRootPath( ignorePath, aDriveNumber ); + iEngine.RemoveNotificationPath( ignorePath ); + CPIXLOGSTRING2("CFileMonitor::RemoveNotificationPaths - RemoveNotificationPath: %S", &ignorePath ); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::Enable +// ----------------------------------------------------------------------------- +// +TInt CFileMonitor::Enable() + { + return iEngine.Enable(); + } + +// ----------------------------------------------------------------------------- +// CFileMonitor::Disable +// ----------------------------------------------------------------------------- +// +TInt CFileMonitor::Disable() + { + return iEngine.Disable(); + } + +// End Of File