metadataengine/server/src/mdsdiskspacenotifier.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 12 Mar 2010 15:44:28 +0200
branchRCL_3
changeset 6 646a02f170b9
parent 0 c53acadfccc6
permissions -rw-r--r--
Revision: 201007 Kit: 201008

/*
* Copyright (c) 2007-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:  This is disk space notifier for Metadata server.*
*/

// INCLUDE FILES
#include "mdsdiskspacenotifier.h"


CMdSDiskSpaceNotifierAO* CMdSDiskSpaceNotifierAO::NewL(
	MMdSDiskSpaceNotifierObserver& aObserver, TInt64 aThreshold, const TDesC& aFilename)
	{
	CMdSDiskSpaceNotifierAO* self = 
		CMdSDiskSpaceNotifierAO::NewLC( aObserver, aThreshold, aFilename );
	CleanupStack::Pop( self );
	return self;
	}

CMdSDiskSpaceNotifierAO* CMdSDiskSpaceNotifierAO::NewLC(
	MMdSDiskSpaceNotifierObserver& aObserver, TInt64 aThreshold, const TDesC& aFilename)
	{
	TDriveNumber driveNumber = GetDriveNumberL( aFilename );

    CMdSDiskSpaceNotifierAO* self = 
    	new ( ELeave ) CMdSDiskSpaceNotifierAO( aObserver, aThreshold, driveNumber );
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
	}

CMdSDiskSpaceNotifierAO::~CMdSDiskSpaceNotifierAO()
	{
	Cancel();

	iFileServerSession.Close();
	}

void CMdSDiskSpaceNotifierAO::RunL()
	{	
	TVolumeInfo volumeInfo;

	if ( iState == CMdSDiskSpaceNotifierAO::ENormal )
		{
		TInt status = iStatus.Int();
		
		switch( status )
			{
			case KErrNone:
			    {
				const TInt error = iFileServerSession.Volume( volumeInfo, iDrive );
				if( error != KErrNone )
				    {
				    StartNotifier();
				    break;
				    }
				
				// Check if free space is less than threshold level
				if( volumeInfo.iFree < iThreshold )
					{
					iObserver.HandleDiskSpaceNotificationL( MMdSDiskSpaceNotifierObserver::ELess );
					iDiskFull = ETrue;
					iState = EIterate;
					iIterationCount = 0;
					SetActive();
					TRequestStatus* status = &iStatus;
					User::RequestComplete( status, KErrNone );
					return;
					}
				else
					{
					iObserver.HandleDiskSpaceNotificationL( MMdSDiskSpaceNotifierObserver::EMore );
					iDiskFull = EFalse;
					}
				StartNotifier();
				break;
			    }

			case KErrArgument:
				User::Leave( status );
				break;
			default:
				break;
			}
		}
	else if ( iState == CMdSDiskSpaceNotifierAO::EIterate )
		{
		const TInt KMaxIterations = 10;
        TInt error = iFileServerSession.Volume( volumeInfo, iDrive );
        if( error != KErrNone )
            {
            iState = ENormal;
            iIterationCount = 0;
            StartNotifier();
            return;
            }

		if ( volumeInfo.iFree < iThreshold )
			{
			iObserver.HandleDiskSpaceNotificationL( MMdSDiskSpaceNotifierObserver::ELess );
			++iIterationCount;
			if ( iIterationCount < KMaxIterations )
				{
				SetActive();
				TRequestStatus* status = &iStatus;
				User::RequestComplete( status, KErrNone );
				return;
				}
			else
				{
		        error = iFileServerSession.Volume( volumeInfo, iDrive );
		        if( error != KErrNone )
		            {
		            iState = ENormal;
		            iIterationCount = 0;
		            StartNotifier();
		            return;
		            }
				if ( volumeInfo.iFree >= iThreshold )
					{
					iDiskFull = EFalse;
					}
				}
			}
		else
			{
			iDiskFull = EFalse;
			}
		iState = ENormal;
		iIterationCount = 0;
		StartNotifier();			
		}
	else
		{
		User::Leave( KErrGeneral );
		}
	}

TInt CMdSDiskSpaceNotifierAO::RunError(TInt aError)
	{
	iObserver.HandleDiskSpaceError( aError );
	
	return KErrNone;
	}

void CMdSDiskSpaceNotifierAO::DoCancel()
	{
	if( IsActive() )
		{	
		iFileServerSession.NotifyDiskSpaceCancel();
		}
	}

CMdSDiskSpaceNotifierAO::CMdSDiskSpaceNotifierAO(
	MMdSDiskSpaceNotifierObserver& aObserver, TInt64 aThreshold, TDriveNumber aDrive)
	: CActive( CActive::EPriorityStandard ), 
	iObserver( aObserver ), iThreshold( aThreshold ), iDrive( aDrive ), iState( CMdSDiskSpaceNotifierAO::ENormal ), iDiskFull( EFalse )
	{
	CActiveScheduler::Add( this );
	}

void CMdSDiskSpaceNotifierAO::ConstructL()
	{	
	TInt KMessageSlotCount = 2; // slots for NotifyDiskSpace and NotifyDiskSpaceCancel

	User::LeaveIfError( iFileServerSession.Connect( KMessageSlotCount ) );
	
	TVolumeInfo volumeInfo;
	const TInt error = iFileServerSession.Volume( volumeInfo, iDrive );	
	if ( (error != KErrNone) || volumeInfo.iFree < iThreshold )
		{
		iDiskFull = ETrue;
		}

	StartNotifier();
	}

void CMdSDiskSpaceNotifierAO::StartNotifier()
	{	
	iFileServerSession.NotifyDiskSpace( iThreshold, iDrive, iStatus );
	
	SetActive();
	}

TDriveNumber CMdSDiskSpaceNotifierAO::GetDriveNumberL( const TDesC& aFilename )
	{
	TLex driveParser( aFilename );
	
	TChar driveChar = driveParser.Get();

	if( 0 == driveChar || TChar( ':' ) != driveParser.Peek() )
		{
		User::Leave( KErrArgument );
		}
		
	TInt driveNumber;
	
	RFs::CharToDrive( driveChar, driveNumber );
	
	return (TDriveNumber)driveNumber;
	}

TBool CMdSDiskSpaceNotifierAO::DiskFull() const
	{
	return iDiskFull;
	}