usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmdismountusbdrives.cpp
branchRCL_3
changeset 15 f92a4f87e424
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmdismountusbdrives.cpp	Tue Aug 31 17:01:47 2010 +0300
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2007-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:  Active Object to dismount usb drives
+*
+*/
+
+
+#include <usb/usblogger.h>
+#include <usb/hostms/srverr.h>
+#include <usb/hostms/msmmpolicypluginbase.h>
+
+#include "msmmdismountusbdrives.h"
+#include "OstTraceDefinitions.h"
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include "msmmdismountusbdrivesTraces.h"
+#endif
+
+
+const TInt KDismountTimeOut   = 6000000; // 6 seconds
+
+
+CMsmmDismountUsbDrives::~CMsmmDismountUsbDrives()
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_CMSMMDISMOUNTUSBDRIVES_DES_ENTRY );
+    
+    Cancel(); 
+    delete iDismountTimer;    
+    iRFs.Close();    
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_CMSMMDISMOUNTUSBDRIVES_DES_EXIT );
+    }
+
+/**
+ * Symbian two phase constructor
+ */
+CMsmmDismountUsbDrives* CMsmmDismountUsbDrives::NewL()
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_NEWL_ENTRY );
+    
+    CMsmmDismountUsbDrives* self = CMsmmDismountUsbDrives::NewLC();
+    CleanupStack::Pop(self);    
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_NEWL_EXIT );
+    return self;
+    }
+
+/**
+ * Symbian two phase constructor. Object pushed to cleanup stack
+ */
+CMsmmDismountUsbDrives* CMsmmDismountUsbDrives::NewLC()
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_NEWLC_ENTRY );
+    
+    CMsmmDismountUsbDrives* self = new (ELeave) CMsmmDismountUsbDrives();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_NEWLC_EXIT );
+    return self;
+    }
+
+/**
+ * Check the status of current dismount request and continue issuing next if no error
+ */
+void CMsmmDismountUsbDrives::RunL()
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_RUNL_ENTRY );
+    
+    iDismountTimer->CancelTimer();    
+    
+    // Indicates there has been an error dismounting a usb drive, report immediately to MSMM plugin and 
+    // abort the process
+    if ( iStatus != KErrNone )
+        {
+        CompleteDismountRequest( iStatus.Int() );
+        }
+    // Indicates we have reached the end of all usb drives dismounting, in other words a success condition
+    else if ( iDriveIndex == KMaxDrives )
+        {
+        CompleteDismountRequest( KErrNone );
+        }
+    // We still have more drives to traverse
+    else if ( iDriveIndex < KMaxDrives )
+        {
+        DoDismount();
+        }
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_RUNL_EXIT );
+    }
+
+/**
+ * Cancel pending notifier and those in queue 
+ */
+void CMsmmDismountUsbDrives::DoCancel()
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_DOCANCEL_ENTRY );
+    
+    iRFs.NotifyDismountCancel(iStatus);
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_DOCANCEL_EXIT );
+    }
+
+CMsmmDismountUsbDrives::CMsmmDismountUsbDrives()
+    : CActive(EPriorityStandard)
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_CMSMMDISMOUNTUSBDRIVES_ENTRY );
+    
+    CActiveScheduler::Add(this);    
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_CMSMMDISMOUNTUSBDRIVES_EXIT );
+    }
+
+void CMsmmDismountUsbDrives::ConstructL()
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_CONSTRUCTL_ENTRY );
+    
+    User::LeaveIfError( iRFs.Connect());
+    iDismountTimer = CDismountTimer::NewL(this);
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_CONSTRUCTL_EXIT );
+    }
+
+/**
+ * Dismount usb drives
+ */
+void CMsmmDismountUsbDrives::DismountUsbDrives(CMsmmPolicyPluginBase& aPlugin, TUSBMSDeviceDescription& aDevice)
+    {    
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_DISMOUNTUSBDRIVES_ENTRY );
+    
+    Cancel();
+    iPlugin = &aPlugin;
+    TUSBMSDeviceDescription& device = iDevicePkgInfo();
+    device = aDevice;
+    iDriveIndex = 0;
+    iRFs.DriveList( iDriveList );
+    DoDismount();
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_DISMOUNTUSBDRIVES_EXIT );
+    }
+
+/**
+ * Callback to CMsmmPolicyPluginBase with either success or failure message
+ */
+void CMsmmDismountUsbDrives::CompleteDismountRequest(const TInt aResult)
+    {
+    THostMsErrData data;
+    if( aResult == KErrNone )
+        data.iError = EHostMsErrNone;
+    else
+        data.iError = EHostMsErrInUse;
+    data.iE32Error = aResult;
+    data.iManufacturerString = iDevicePkgInfo().iManufacturerString;
+    data.iProductString = iDevicePkgInfo().iProductString;
+    data.iDriveName = 0x0;
+   
+    TRAP_IGNORE(iPlugin->SendErrorNotificationL(data));
+    }
+
+/**
+ * Dismount next usb drive
+ */
+void CMsmmDismountUsbDrives::DoDismount()
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_DODISMOUNT_ENTRY );
+       
+    TDriveInfo info;
+    TInt err = KErrNone;
+    for ( ; iDriveIndex < KMaxDrives; iDriveIndex++ )
+        {
+        if ( iDriveList[iDriveIndex] )
+            {
+            err = iRFs.Drive( info , iDriveIndex );            
+            if ( info.iConnectionBusType == EConnectionBusUsb &&                 
+                 info.iDriveAtt & KDriveAttExternal && 
+                 err == KErrNone  )
+                {
+                OstTrace0( TRACE_NORMAL, CMSMMDISMOUNTUSBDRIVES_DODISMOUNT, 
+                        "CMsmmDismountUsbDrives::DoDismount Dismount notify request" );
+                iRFs.NotifyDismount( iDriveIndex, iStatus, EFsDismountNotifyClients );                
+                iDismountTimer->StartTimer();
+                SetActive();
+                OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_DODISMOUNT_EXIT );
+                return;
+                }                     
+            }
+        }
+    // Indicates we have gone through all the drives and no more usb drives left to request dismount
+    CompleteDismountRequest( KErrNone );
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_DODISMOUNT_EXIT_DUP1 );
+    }
+
+
+/**
+ * Callback function from CDismountTimer after 6 seconds indicating a usb drive is not released by another process, report it as an error
+ */
+void CMsmmDismountUsbDrives::TimerExpired()
+    {
+    OstTraceFunctionEntry0( CMSMMDISMOUNTUSBDRIVES_TIMEREXPIRED_ENTRY );
+    
+    Cancel();
+    iDismountTimer->CancelTimer();    
+    CompleteDismountRequest( KErrInUse );    
+    OstTraceFunctionExit0( CMSMMDISMOUNTUSBDRIVES_TIMEREXPIRED_EXIT );
+    }    
+
+//CDismountTimer
+
+CDismountTimer* CDismountTimer::NewL( MTimerNotifier* aTimeOutNotify)
+    {
+    OstTraceFunctionEntry0( CDISMOUNTTIMER_NEWL_ENTRY );
+        
+    CDismountTimer* self = CDismountTimer::NewLC( aTimeOutNotify );
+    CleanupStack::Pop(self);
+    OstTraceFunctionExit0( CDISMOUNTTIMER_NEWL_EXIT );
+    return self;
+    }
+
+CDismountTimer* CDismountTimer::NewLC( MTimerNotifier* aTimeOutNotify )
+    {
+    OstTraceFunctionEntry0( CDISMOUNTTIMER_NEWLC_ENTRY );
+        
+    CDismountTimer* self = new (ELeave) CDismountTimer( aTimeOutNotify );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    OstTraceFunctionExit0( CDISMOUNTTIMER_NEWLC_EXIT );
+    return self;
+    }
+
+CDismountTimer::CDismountTimer( MTimerNotifier* aTimeOutNotify):
+    CTimer(EPriorityStandard), 
+    iNotify(aTimeOutNotify)    
+    {
+    OstTraceFunctionEntry0( CDISMOUNTTIMER_CDISMOUNTTIMER_CONS_ENTRY );
+    }    
+
+CDismountTimer::~CDismountTimer()
+    {
+    OstTraceFunctionEntry0( CDISMOUNTTIMER_CDISMOUNTTIMER_DES_ENTRY );
+    
+    Cancel();
+    OstTraceFunctionExit0( CDISMOUNTTIMER_CDISMOUNTTIMER_DES_EXIT );
+    }
+
+void CDismountTimer::ConstructL()
+    {
+    OstTraceFunctionEntry0( CDISMOUNTTIMER_CONSTRUCTL_ENTRY );
+        
+    if ( !iNotify )    
+        {
+        User::Leave(KErrArgument);    
+        }
+    CTimer::ConstructL();
+    CActiveScheduler::Add(this);
+    OstTraceFunctionExit0( CDISMOUNTTIMER_CONSTRUCTL_EXIT );
+    }
+
+void CDismountTimer::RunL()
+    {
+    OstTraceFunctionEntry0( CDISMOUNTTIMER_RUNL_ENTRY );
+    
+    // Timer request has completed, so notify the timer's owner
+    iNotify->TimerExpired();
+    OstTraceFunctionExit0( CDISMOUNTTIMER_RUNL_EXIT );
+    }
+void CDismountTimer::CancelTimer()
+    {
+    OstTraceFunctionEntry0( CDISMOUNTTIMER_CANCELTIMER_ENTRY );
+     
+    Cancel();    
+    OstTraceFunctionExit0( CDISMOUNTTIMER_CANCELTIMER_EXIT );
+    }
+
+void CDismountTimer::StartTimer()
+    {
+    OstTraceFunctionEntry0( CDISMOUNTTIMER_STARTTIMER_ENTRY );
+    
+    After( KDismountTimeOut );  
+    OstTraceFunctionExit0( CDISMOUNTTIMER_STARTTIMER_EXIT );
+    }
+// End of File