diff -r 0efa10d348c0 -r a5a39a295112 contentpublishingsrv/contentharvester/contentharvesterswiplugin/src/chswiusbhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/contentpublishingsrv/contentharvester/contentharvesterswiplugin/src/chswiusbhandler.cpp Wed Sep 01 12:22:09 2010 +0100 @@ -0,0 +1,307 @@ +/* +* Copyright (c) 2007 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: Software Installer plug-in usb handler +* +*/ + + +// INCLUDE FILES + +#include "chswiusbhandler.h" +#include "chswiplugin.h" +#include "chswimassmodeobserver.h" +#include + +// CONSTANTS +const TInt KCallBackDelay = 5000000; + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::NewL() +// two-phase constructor +// ---------------------------------------------------------------------------- +// +CCHSwiUsbHandler* CCHSwiUsbHandler::NewL( + MCHSwiMassModeObserver* aMassModeObserver, + RFs& aFs ) + { + CCHSwiUsbHandler* self = + new(ELeave) CCHSwiUsbHandler( aMassModeObserver, aFs ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::CCHSwiUsbHandler() +// C++ default constructor +// ---------------------------------------------------------------------------- +// +CCHSwiUsbHandler::CCHSwiUsbHandler( MCHSwiMassModeObserver* aMassModeObserver, + RFs& aFs ) + : CActive( CActive::EPriorityUserInput ), + iLastDriveScanError( KErrNone ), + iMassModeObserver( aMassModeObserver ), + iFs( aFs ), + iDriveFlags( 0 ) + { + CActiveScheduler::Add( this ); + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::ConstructL() +// Symbian default constructor +// ---------------------------------------------------------------------------- +// +void CCHSwiUsbHandler::ConstructL() + { + User::LeaveIfError( iTimer.CreateLocal() ); + + iLastDriveScanError = ScanDrivesAndUpdateFlag( EFalse ); + + if ( iLastDriveScanError != KErrNone ) + { + HandleDriveError(); + } + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::~CCHSwiUsbHandler() +// destructor +// ---------------------------------------------------------------------------- +// +CCHSwiUsbHandler::~CCHSwiUsbHandler() + { + Cancel(); + iTimer.Close(); + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::SynchronousDriveScan() +// Performs synchronous drive scan. Checks whether Mass Drive is available +// and updates the flag in observer. +// ---------------------------------------------------------------------------- +// +void CCHSwiUsbHandler::SynchronousDriveScan() + { + iLastDriveScanError = ScanDrivesAndUpdateFlag( iLastDriveScanError == KErrNone ); + + if ( iLastDriveScanError != KErrNone ) + { + HandleDriveError(); + } + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::PostponedDriveScan() +// Starts postponed drive scan. +// ---------------------------------------------------------------------------- +// +void CCHSwiUsbHandler::PostponedDriveScan() + { + Cancel(); + iTimer.After( iStatus, KCallBackDelay ); + SetActive(); + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::RunL() +// Handles postponed drive scan. +// Executed either after call to PostponedDriveScan or in case of drive reading +// errors in SynchronousDriveScan or ConstructL. +// ---------------------------------------------------------------------------- +// +void CCHSwiUsbHandler::RunL() + { + TBool massModeBeforeScan = iMassModeObserver->IsMassStorageMode(); + TInt errorBeforeScan = iLastDriveScanError; + + SynchronousDriveScan(); + + if ( iLastDriveScanError == KErrNone ) + { + iMassModeObserver->HandleSuccessfulAsynchDriveScan(); + + // CCHSwiUsbObserver can't detect app uninstall when app had been installed on removable + // memory card, the memory card was removed during mass mode, and then mass + // mode was deactivated. + // Additionaly, we need to update widgets when recovering from error. + if ( !iMassModeObserver->IsMassStorageMode() && + ( massModeBeforeScan || errorBeforeScan != KErrNone ) ) + { + iMassModeObserver->HandleMassStorageModeEndEvent(); + } + } + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::HandleDriveError() +// Handles drive access errors by launching new postponed scan. +// ---------------------------------------------------------------------------- +void CCHSwiUsbHandler::HandleDriveError() + { + Cancel(); + iMassModeObserver->SetMassStorageMode( ETrue ); + + iTimer.After( iStatus, KCallBackDelay ); + SetActive(); + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::ScanDrivesAndUpdateFlag() +// Scans drives and updates Mass Mode flag in the observer. +// ---------------------------------------------------------------------------- +TInt CCHSwiUsbHandler::ScanDrivesAndUpdateFlag( TBool aFlagsValid ) + { + TInt error( KErrNone ); + + if( aFlagsValid ) + { + // iDriveFlags is valid, we can use deltaDriveFlags to avoid + // unnecessary calls to DriveInfo::GetDriveStatus + TInt driveFlags = 0; + TInt deltaDriveFlags = 0; + + error = ScanDrives( driveFlags ); + + if ( error == KErrNone ) + { + deltaDriveFlags = iDriveFlags ^ driveFlags; + iDriveFlags = driveFlags; + } + + if ( deltaDriveFlags ) + { + error = UpdateMassModeFlag(); + } + } + else + { + error = ScanDrives( iDriveFlags ); + + if ( error == KErrNone ) + { + error = UpdateMassModeFlag(); + } + } + + return error; + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::UpdateMassModeFlag() +// Updates Mass Mode flag in the observer. +// ---------------------------------------------------------------------------- +TInt CCHSwiUsbHandler::UpdateMassModeFlag() + { + TInt flags = iDriveFlags; + TBool massMemoryPresent = EFalse; + + for( TInt DriveNo = EDriveA + 1 ; DriveNo <= EDriveY; DriveNo++ ) + { + flags = flags >> 1; + if( flags & 01 ) + { + TUint status( 0 ); + TInt error = DriveInfo::GetDriveStatus( iFs, DriveNo, status ); + + if( error != KErrNone ) + { + return error; + } + + if( ( status & DriveInfo::EDriveExternallyMountable ) + && ( status & DriveInfo::EDriveInternal ) ) + { + // Internal Memory + massMemoryPresent = ETrue; + break; + } + } + } + + iMassModeObserver->SetMassStorageMode( !massMemoryPresent ); + return KErrNone; + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::RunError() +// Ignore errors from RunL. +// ---------------------------------------------------------------------------- +// +TInt CCHSwiUsbHandler::RunError( TInt /* aError */ ) + { + return KErrNone; // indicates error was handled + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::DoCancel() +// Cancel the MMC event handler +// ---------------------------------------------------------------------------- +void CCHSwiUsbHandler::DoCancel() + { + iTimer.Cancel(); + } + +// ---------------------------------------------------------------------------- +// CCHSwiUsbHandler::ScanDrives( TInt& aDriveFlags ) +// Scans drives and records a bit flag for those that exist and are +// suitable for installing widgets to. +// ---------------------------------------------------------------------------- +// +TInt CCHSwiUsbHandler::ScanDrives( TInt& aDriveFlags ) + { + // List all drives in the system + TDriveList driveList; + TInt error = iFs.DriveList( driveList ); + + if ( KErrNone == error ) + { + for ( TInt driveNumber = EDriveY; + driveNumber >= EDriveA; + driveNumber-- ) + { + // The drives that will be filtered out are the same ones that + // WidgetInstaller filters out in CWidgetUIHandler::SelectDriveL() + if ( (EDriveD == driveNumber) + || !driveList[driveNumber] ) + { + // EDriveD is a temporary drive usually a RAM disk + continue; + } + + TVolumeInfo volInfo; + if ( iFs.Volume( volInfo, driveNumber ) != KErrNone ) + { + // volume is not usable (e.g. no media card inserted) + continue; + } + if ( (volInfo.iDrive.iType == EMediaNotPresent) || + (volInfo.iDrive.iType == EMediaRom) || + (volInfo.iDrive.iType == EMediaRemote) || + (volInfo.iDrive.iDriveAtt & KDriveAttRom) || + (volInfo.iDrive.iDriveAtt & KDriveAttSubsted) ) + { + // not a suitable widget install drive + continue; + } + + // found a usable drive + aDriveFlags |= (1 << driveNumber); + } + } + + return error; + } +