harvester/monitorplugins/mmcplugin/src/mmcmonitorplugin.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/harvester/monitorplugins/mmcplugin/src/mmcmonitorplugin.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,348 @@
+/*
+* Copyright (c) 2006-2009 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:  Monitors MMC insertions and removals.*
+*/
+
+
+#include "mmcmonitorplugin.h"
+#include "harvesterlog.h"
+#include "mdsfileserverpluginclient.h"
+#include "fsutil.h"
+#include "harvestercenreputil.h"
+#include <driveinfo.h>
+
+#include <e32cmn.h>
+
+_LIT( KColon, ":" );
+
+// construct/destruct
+CMMCMonitorPlugin* CMMCMonitorPlugin::NewL()
+    {
+    CMMCMonitorPlugin* self = new (ELeave) CMMCMonitorPlugin();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void CMMCMonitorPlugin::ConstructL() // second-phase constructor
+    {
+    WRITELOG( "CMMCMonitorPlugin::ConstructL" );
+
+    iMMCMonitor = CMMCMonitorAO::NewL();
+    iMountTask = CMMCMountTaskAO::NewL();
+    iUsbMonitor = CMMCUsbAO::NewL();
+    iMdEClient = NULL;
+    }
+    
+CMMCMonitorPlugin::~CMMCMonitorPlugin() // destruct
+    {
+    WRITELOG( "CMMCMonitorPlugin::~CMMCMonitorPlugin" );
+    
+    if (iMMCMonitor)
+    	{
+    	iMMCMonitor->StopMonitoring();
+    	delete iMMCMonitor;
+    	}
+    
+	if (iUsbMonitor)
+    	{
+    	iUsbMonitor->StopMonitoring();
+    	delete iUsbMonitor;
+    	}
+    
+	if (iMountTask)
+    	{
+    	delete iMountTask;
+    	}
+	
+	delete iMmcScanner;
+	delete iHddScanner;
+    }
+
+TBool CMMCMonitorPlugin::StartMonitoring( MMonitorPluginObserver& aObserver,
+    CMdESession* aMdEClient, CContextEngine* /*aCtxEngine*/, 
+    CHarvesterPluginFactory* aHarvesterPluginFactory )
+    {
+    WRITELOG( "CMMCMonitorPlugin::StartMonitoring" );
+
+    iObserver = &aObserver;
+    TRAPD( err, iMdEClient = CMdEHarvesterSession::NewL( *aMdEClient ) );
+    if( err != KErrNone )
+    	{
+    	return EFalse;
+    	}
+    
+    iMountTask->SetMonitorObserver( aObserver );
+    iMountTask->SetMdeSession( iMdEClient );
+    iMountTask->SetHarvesterPluginFactory( aHarvesterPluginFactory );
+    
+    // get present media IDs before last shutdown
+    RArray<TMdEMediaInfo> medias;
+    TRAP_IGNORE( iMdEClient->GetPresentMediasL( medias ) );
+	
+    // update db present status 
+    TRAP( err, StartMonitoringAllMMCsL( medias ) );
+    if ( err != KErrNone )
+        {
+        return EFalse;
+        }
+    
+    TChar driveLetter( 0 );
+	TBool presentState( EFalse );
+    
+	TUint32 hdMediaId( 0 );
+    hdMediaId = iMountTask->GetInternalDriveMediaId();
+    TBool alreadyWaited( EFalse );
+    
+    
+    for ( TInt i = 0; i < medias.Count(); i++ )
+    	{
+    	TRAP_IGNORE( iMdEClient->GetMediaL( medias[i].iMediaId, driveLetter, presentState ) );
+    	
+    	if ( presentState && medias[i].iMediaId != hdMediaId )
+    		{
+    		// scan MMC if card was in phone
+    		TRAP_IGNORE( iMmcScanner = CMmcScannerAO::NewL( medias[i].iMediaId, iMdEClient, iObserver,
+    		    				aHarvesterPluginFactory, CActive::EPriorityHigh, alreadyWaited ) );
+    		alreadyWaited = ETrue;
+    		}
+    	}
+ 
+    // scan mass storage to catch all chances even if battery dies during operation that should  be catched
+    if( hdMediaId )
+		{
+		TBool exists( EFalse );
+		TRAP_IGNORE( exists= iMdEClient->GetMediaL( hdMediaId, driveLetter, presentState ) );
+		
+		if ( exists )
+			{
+			WRITELOG("CMMCMonitorPlugin::StartMonitoring - start mass storage scan");
+			
+			TMdEMediaInfo hdInfo;
+			hdInfo.iMediaId = hdMediaId;
+			hdInfo.iDrive = driveLetter;
+			medias.Append( hdInfo );
+			
+			TRAP_IGNORE( iHddScanner = CMmcScannerAO::NewL( hdMediaId, iMdEClient, iObserver,
+			    				aHarvesterPluginFactory, CActive::EPriorityUserInput, alreadyWaited ));
+			}
+		}
+
+    iMMCMonitor->StartMonitoring( *this, medias );
+    
+    medias.Close();
+ 
+   	return iUsbMonitor->StartMonitoring( *this );
+    }
+
+TBool CMMCMonitorPlugin::StopMonitoring()
+    {
+    WRITELOG( "CMMCMonitorPlugin::StopMonitoring" );
+    
+    iMMCMonitor->StopMonitoring();
+    return iUsbMonitor->StopMonitoring();
+    }
+
+TBool CMMCMonitorPlugin::ResumeMonitoring( MMonitorPluginObserver& /*aObserver*/,
+    CMdESession* /*aMdEClient*/, CContextEngine* /*aCtxEngine*/,
+    CHarvesterPluginFactory* /*aHarvesterPluginFactory*/ )
+    {
+    WRITELOG( "CMMCMonitorPlugin::ResumeMonitoring" );
+    iMountTask->SetCachingStatus( EFalse );
+    return ETrue;
+    }
+
+TBool CMMCMonitorPlugin::PauseMonitoring()
+    {
+    WRITELOG( "CMMCMonitorPlugin::PauseMonitoring" ); // DEBUG INFO
+    iMountTask->SetCachingStatus( ETrue );
+    return ETrue;
+    }
+
+// constructor support
+// don't export these, because used only by functions in this DLL, eg our NewLC()
+CMMCMonitorPlugin::CMMCMonitorPlugin() // first-phase C++ constructor
+    {
+    // No implementation required
+    }
+
+void CMMCMonitorPlugin::AddNotificationPathL( TChar aDrive )
+    {
+    WRITELOG( "CMMCMonitorPlugin::AddNotificationPath" );
+
+    // 1 in length is for aDrive
+    HBufC* path = HBufC::NewLC( 1 + KColon.iTypeLength );
+    TPtr pathPtr = path->Des();
+    pathPtr.Append( aDrive );
+    pathPtr.Append( KColon );    
+    
+	CHarvesterCenRepUtil* cenRepoUtil = CHarvesterCenRepUtil::NewLC();
+	cenRepoUtil->AddIgnorePathsToFspL( pathPtr );
+	cenRepoUtil->FspEngine().AddNotificationPath( pathPtr );
+	CleanupStack::PopAndDestroy( cenRepoUtil );    
+    CleanupStack::PopAndDestroy( path );
+    }
+
+void CMMCMonitorPlugin::MountEvent( TChar aDriveChar, TUint32 aMediaID, TMMCEventType aEventType )
+    {
+    WRITELOG( "CMMCMonitorPlugin::MountEvent" );
+
+    TMountData* mountData = NULL;
+    mountData = new TMountData;
+    if ( !mountData )
+        {
+        return;
+        }
+    if( aMediaID != 0 && aEventType == EMounted)
+    	{
+	    RFs fs;
+	    const TInt err = fs.Connect();
+	    if ( err != KErrNone )
+	    	{
+	        delete mountData;
+	    	return;
+	    	}
+
+	    TUint status;
+	    TInt drive;
+	    fs.CharToDrive( aDriveChar, drive );
+		if( DriveInfo::GetDriveStatus( fs, drive, status ) == KErrNone )
+			{
+			//The "Out of disk space" mde query uses the MdE_Preferences table
+			if( !(status & DriveInfo::EDriveInternal) )
+				{
+				iMdEClient->AddMemoryCard( aMediaID );
+				}
+			}
+		
+		fs.Close();
+    	}
+
+    mountData->iDrivePath.Append( aDriveChar );
+    mountData->iDrivePath.Append( KColon );
+    mountData->iMediaID = aMediaID;
+    
+    switch ( aEventType )
+        {
+        case EMounted:
+            {
+            WRITELOG( "CMMCMonitorPlugin::MountEvent with parameter EMounted" );
+            mountData->iMountType = TMountData::EMount;
+            iMountTask->StartMount( *mountData );
+            }
+        break;
+        
+        case EDismounted:
+            {
+            if( aMediaID == 0 )
+            	{
+            	TRAP_IGNORE( mountData->iMediaID = FSUtil::GetPreviousMediaIDL( iMdEClient, aDriveChar ) );
+            	}
+            if( mountData->iMediaID )
+            	{
+	            WRITELOG( "CMMCMonitorPlugin::MountEvent with parameter EDismounted" );
+	            mountData->iMountType = TMountData::EUnmount;
+	            iMountTask->StartUnmount( *mountData );
+            	}
+            }
+        break;
+        
+        case EFormatted:
+            {
+            WRITELOG( "CMMCMonitorPlugin::MountEvent with parameter EFormatted" );
+            mountData->iMountType = TMountData::EFormat;
+            iMountTask->StartUnmount( *mountData );
+            }
+        break;
+        
+        default:
+            {
+            _LIT( KLogPanic, "unknown state" );
+            User::Panic( KLogPanic, KErrArgument );
+            }
+        break;
+        }
+    }
+
+void CMMCMonitorPlugin::StartMonitoringAllMMCsL( RArray<TMdEMediaInfo>& aMedias )
+    {
+    WRITELOG( "CMMCMonitorPlugin::StartMonitoringAllMMCs" );
+    TInt count( 0 );
+    
+    RFs fs;
+    User::LeaveIfError( fs.Connect() );
+    CleanupClosePushL( fs );
+        
+    TDriveInfo driveInfo;
+    TDriveList driveList;
+    TInt numOfElements( 0 );
+    DriveInfo::GetUserVisibleDrives( fs, 
+                                                        driveList, 
+                                                        numOfElements, 
+                                                        KDriveAttExclude | KDriveAttRemote | KDriveAttRom );
+    
+    TInt i( 0 );
+    TChar drive;
+    const TInt acount = driveList.Length();
+    const TInt mediaCount = aMedias.Count();
+    
+    // set removed medias to not present
+    for ( i = 0; i < mediaCount; i++ )
+    	{
+    	TInt driveNum(0);
+    	fs.CharToDrive( aMedias[i].iDrive, driveNum );
+    	TUint32 mediaId = FSUtil::MediaID( fs, driveNum );
+    	if ( mediaId != aMedias[i].iMediaId ) 
+    		{
+    		iMdEClient->SetMediaL( aMedias[i].iMediaId, aMedias[i].iDrive, EFalse );
+    		}
+    	}
+    
+    for ( i = 0; i < acount; i++ )
+        {
+        if ( driveList[i] > 0 )
+            {
+            TUint driveStatus( 0 );
+            DriveInfo::GetDriveStatus( fs, i, driveStatus ); 
+
+            if ( driveStatus & DriveInfo::EDriveUsbMemory )
+                {
+                driveList[i] = 0;
+                continue;
+                }
+            
+            fs.Drive( driveInfo, i );
+            if ( driveInfo.iDriveAtt & KDriveAttRemovable && driveInfo.iType != EMediaNotPresent )
+                {
+                count++; // DEBUG INFO
+                
+                fs.DriveToChar( i, drive );
+                
+                // set media id to MdE
+                TUint32 mediaId = FSUtil::MediaID( fs, i );
+                if ( mediaId != 0 )
+                    {
+                    iMdEClient->SetMediaL( mediaId, drive, ETrue );
+
+                    AddNotificationPathL( drive );
+                    }
+                }
+            }
+        }
+    
+    CleanupStack::PopAndDestroy( &fs ); 
+    
+    WRITELOG1( "CMMCMonitorPlugin::StartMonitoringAllMMCs found %d MMCs", count );
+    }