--- /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;
+ }