diff -r d3e8e7d462dd -r f92a4f87e424 usbmgmt/usbmgr/host/functiondrivers/ms/msmm/server/src/msmmdismountusbdrives.cpp --- /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 +#include +#include + +#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