harvester/client/src/harvestereventobserverao.cpp
changeset 0 c53acadfccc6
child 8 6752808b2036
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/harvester/client/src/harvestereventobserverao.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,207 @@
+/*
+* 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:  
+*
+*/
+#include <e32svr.h>
+#include <harvestereventenum.h>
+
+#include "harvestereventobserverao.h"
+#include "harvesterclient.h"
+
+const TInt KHarverterEventQueueSize = 32;
+
+CHarvesterEventObserverAO::CHarvesterEventObserverAO( 
+		RHarvesterClient& aHarvesterClient ) :
+	CActive(CActive::EPriorityStandard), // Standard priority
+	iHarvesterClient( aHarvesterClient )
+	{
+	}
+
+CHarvesterEventObserverAO* CHarvesterEventObserverAO::NewLC( 
+		RHarvesterClient& aHarvesterClient )
+	{
+	CHarvesterEventObserverAO* self = 
+		new ( ELeave ) CHarvesterEventObserverAO( aHarvesterClient );
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+CHarvesterEventObserverAO* CHarvesterEventObserverAO::NewL( 
+		RHarvesterClient& aHarvesterClient )
+	{
+	CHarvesterEventObserverAO* self = 
+		CHarvesterEventObserverAO::NewLC( aHarvesterClient );
+	CleanupStack::Pop( self ); // self;
+	return self;
+	}
+
+void CHarvesterEventObserverAO::ConstructL()
+	{
+	CActiveScheduler::Add( this ); // Add to scheduler
+	}
+
+CHarvesterEventObserverAO::~CHarvesterEventObserverAO()
+	{
+	Cancel(); // Cancel any request, if outstanding
+
+	for(TInt i = iObservers.Count(); --i >= 0;)
+		{
+		THarvesterEventObserver& observer = *(iObservers[i]);
+
+		TIpcArgs ipcArgs( observer.iObserverInfo.iObserverId, 
+				iHarvesterEventQueue.Handle() );
+
+		iHarvesterClient.Send( EUnregisterHarvesterEvent, ipcArgs );
+		}
+
+	iHarvesterEventQueue.Close();
+	
+	iObservers.ResetAndDestroy();
+	}
+
+void CHarvesterEventObserverAO::DoCancel()
+	{
+	iHarvesterEventQueue.CancelDataAvailable();
+	}
+
+void CHarvesterEventObserverAO::AddHarvesterEventObserverL( 
+			MHarvesterEventObserver& aHarvesterEventObserver, 
+			TInt aHEObserverType,
+    		TInt aNotificationInterval )
+	{
+	RHandleBase& queueHandle = GetEventQueueHandleL();
+
+	THarvesterEventObserver* observer = 
+			new (ELeave) THarvesterEventObserver( aHarvesterEventObserver );
+	CleanupStack::PushL( observer );
+
+	// Init client side values
+	observer->iObserverInfo.iQueueHandle = queueHandle.Handle();
+	observer->iObserverInfo.iObserverId = NextObserverId();
+	observer->iObserverInfo.iObserverType = aHEObserverType;
+	observer->iObserverInfo.iNotificationInterval = aNotificationInterval;
+
+	iObservers.AppendL( observer );
+
+	CleanupStack::Pop( observer );
+
+	TPckg<THarvesterEventObserverInfo> pckgObserverInfo( observer->iObserverInfo );
+	TIpcArgs ipcArgs( &pckgObserverInfo, queueHandle );
+
+	TInt err = iHarvesterClient.SendReceive( ERegisterHarvesterEvent, ipcArgs );
+
+	User::LeaveIfError( err );
+
+	if( !IsActive() )
+		{
+		iHarvesterEventQueue.NotifyDataAvailable( iStatus );
+		SetActive(); // Tell scheduler a request is active
+		}
+	}
+
+void CHarvesterEventObserverAO::RemoveHarvesterEventObserverL( 
+		MHarvesterEventObserver& aHarvesterEventObserver )
+	{
+	// clear all observers which match to callback instance
+	for(TInt i = iObservers.Count(); --i >= 0;)
+		{
+		THarvesterEventObserver* observer = iObservers[i];
+		if( &observer->iObserver == &aHarvesterEventObserver )
+			{
+			TIpcArgs ipcArgs( observer->iObserverInfo.iObserverId, 
+							iHarvesterEventQueue.Handle() );
+			iHarvesterClient.Send( EUnregisterHarvesterEvent, ipcArgs );
+			iObservers.Remove( i );
+			delete observer;
+			}
+		}
+
+	// close event queue if all observers are removed
+	if( iObservers.Count() == 0 )
+		{
+		Cancel();
+		iHarvesterEventQueue.Close();
+		}
+	}
+
+void CHarvesterEventObserverAO::RunL()
+	{
+	User::LeaveIfError( iStatus.Int() );
+
+	THarvesterEventNotification received;
+	while( iHarvesterEventQueue.Receive( received ) != KErrUnderflow )
+		{
+		for(TInt i = iObservers.Count(); --i >= 0;)
+			{
+			THarvesterEventObserver& observer = *(iObservers[i]);
+			if( observer.iObserverInfo.iObserverId == received.iObserverId )
+				{
+				observer.iObserver.HarvestingUpdated( received.iObserverType,  
+						received.iCurrentState, received.iItemsLeft );
+				break;
+				}
+			}
+		}
+
+	if( iObservers.Count() > 0 )
+		{
+		SetActive();
+		iHarvesterEventQueue.NotifyDataAvailable( iStatus );
+		}
+	}
+
+TInt CHarvesterEventObserverAO::RunError(TInt /*aError*/)
+	{
+	return KErrNone;
+	}
+
+TUint CHarvesterEventObserverAO::NextObserverId()
+	{
+	// Sort by observer IDs
+	iObservers.Sort( TLinearOrder<THarvesterEventObserver>(
+			THarvesterEventObserver::CompareObserverIds ) );
+
+	// Find smallest unused observer ID 
+	const TUint count = iObservers.Count();
+	for( TUint i = 0; i < count; i++ )
+		{
+		// Return first free observer ID 
+		if( iObservers[i]->iObserverInfo.iObserverId != i )
+			{
+			return i;
+			}
+		}
+
+	if( count )
+	    {
+	    // No free observer ID found, so return largest observer ID + 1 
+	    return iObservers[count - 1]->iObserverInfo.iObserverId + 1;
+	    }
+	// No observer IDs assigned
+	return 0;
+	}
+
+RHandleBase& CHarvesterEventObserverAO::GetEventQueueHandleL()
+	{
+	// create new message queue
+	if( KNullHandle == iHarvesterEventQueue.Handle() )
+		{
+		TInt err = iHarvesterEventQueue.CreateGlobal( KNullDesC, KHarverterEventQueueSize );
+		User::LeaveIfError( err );
+		}
+
+	return iHarvesterEventQueue;
+	}