--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/harvester/common/src/harvestereventmanager.cpp Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,460 @@
+/*
+* Copyright (c) 2006-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 "harvestereventmanager.h"
+#include "harvesterlog.h"
+
+const TInt KHarvesterEventManagerTLSKey = 0x200104D9;
+
+CHarvesterEventManager::CHarvesterEventManager()
+ {
+ }
+
+void CHarvesterEventManager::ConstructL()
+ {
+ }
+
+CHarvesterEventManager::~CHarvesterEventManager()
+ {
+ for ( TInt i = 0; i < iEventQueues.Count(); i++)
+ {
+ iEventQueues[i]->Close();
+ }
+ iEventQueues.ResetAndDestroy();
+ iEventQueues.Close();
+
+ iRegisteredObservers.ResetAndDestroy();
+ iRegisteredObservers.Close();
+
+ iEventStatuses.Close();
+ }
+
+EXPORT_C CHarvesterEventManager* CHarvesterEventManager::GetInstanceL()
+ {
+ WRITELOG( "CHarvesterEventManager::GetInstanceL" );
+
+ CHarvesterEventManagerStaticData* data =
+ static_cast<CHarvesterEventManagerStaticData*>(
+ UserSvr::DllTls( KHarvesterEventManagerTLSKey ) );
+
+ CHarvesterEventManager* instance = NULL;
+
+ if ( !data )
+ {
+ instance = new (ELeave) CHarvesterEventManager();
+ CleanupStack::PushL( instance );
+ instance->ConstructL();
+ UserSvr::DllSetTls( KHarvesterEventManagerTLSKey,
+ new (ELeave) CHarvesterEventManagerStaticData(instance) );
+ CleanupStack::Pop( instance );
+ }
+ else
+ {
+ instance = data->iHEM;
+ data->iRefCount++;
+ }
+
+ return instance;
+ }
+
+EXPORT_C void CHarvesterEventManager::ReleaseInstance()
+ {
+ WRITELOG( "CHarvesterEventManager::ReleaseInstance" );
+ CHarvesterEventManagerStaticData* data =
+ static_cast<CHarvesterEventManagerStaticData*>(
+ UserSvr::DllTls( KHarvesterEventManagerTLSKey ) );
+ if ( data )
+ {
+ data->iRefCount--;
+ if ( data->iRefCount <= 0 )
+ {
+ // destroy the singleton and free TLS
+ delete data;
+ UserSvr::DllFreeTls( KHarvesterEventManagerTLSKey );
+ }
+ }
+ }
+
+EXPORT_C void CHarvesterEventManager::IncreaseItemCount(
+ HarvesterEventObserverType aHEObserverType, TUint aCount )
+ {
+ TEventStatus* eventStatus = GetEventStatus( aHEObserverType );
+ WRITELOG2( "CHarvesterEventManager::IncreaseItemCount(%d) type = %d", aCount, aHEObserverType);
+
+#ifdef _DEBUG
+ switch(aHEObserverType)
+ {
+ case EHEObserverTypePlaceholder:
+ WRITELOG( "CHarvesterEventManager::IncreaseItemCount() EHEObserverTypePlaceholder");
+ break;
+ case EHEObserverTypeMMC:
+ WRITELOG( "CHarvesterEventManager::IncreaseItemCount() EHEObserverTypeMMC");
+ break;
+ case EHEObserverTypeOverall:
+ WRITELOG( "CHarvesterEventManager::IncreaseItemCount() EHEObserverTypeOverall");
+ break;
+ default:
+ WRITELOG( "CHarvesterEventManager::IncreaseItemCount() Unknown type!");
+ };
+#endif
+
+ if( eventStatus )
+ {
+ WRITELOG1( "CHarvesterEventManager::IncreaseItemCount() itemsleft = %d old ", eventStatus->iItemsLeft);
+ eventStatus->iItemsLeft += aCount;
+ WRITELOG1( "CHarvesterEventManager::IncreaseItemCount() itemsleft = %d ", eventStatus->iItemsLeft);
+ }
+ else
+ {
+ TEventStatus eventStatus;
+ eventStatus.iCurrentState = EHEStateStarted;
+ WRITELOG1( "CHarvesterEventManager::IncreaseItemCount() itemsleft = %d old", aCount);
+ eventStatus.iItemsLeft = aCount;
+ WRITELOG1( "CHarvesterEventManager::IncreaseItemCount() itemsleft = %d ", aCount);
+ eventStatus.iObserverType = aHEObserverType;
+ iEventStatuses.Append( eventStatus );
+ }
+ }
+
+EXPORT_C TBool CHarvesterEventManager::DecreaseItemCountL(
+ HarvesterEventObserverType aHEObserverType, TUint aCount )
+ {
+ TEventStatus* eventStatus = GetEventStatus( aHEObserverType );
+ WRITELOG2( "CHarvesterEventManager::DecreaseItemCountL(%d) type = %d ", aCount, aHEObserverType);
+
+#ifdef _DEBUG
+ switch(aHEObserverType)
+ {
+ case EHEObserverTypePlaceholder:
+ WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypePlaceholder");
+ break;
+ case EHEObserverTypeMMC:
+ WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypeMMC");
+ break;
+ case EHEObserverTypeOverall:
+ WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypeOverall");
+ break;
+ default:
+ WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() Unknown type!");
+ };
+#endif
+
+ if( eventStatus )
+ {
+ WRITELOG1( "CHarvesterEventManager::DecreaseItemCountL() iItemsLeft = %d old", eventStatus->iItemsLeft);
+ TUint newCount = eventStatus->iItemsLeft - aCount;
+
+ // check for wrap
+ if( newCount > eventStatus->iItemsLeft )
+ {
+ newCount = 0;
+ }
+
+ // event doesn't need to be sent, if count hasn't changed
+ if( newCount == eventStatus->iItemsLeft )
+ {
+ return EFalse;
+ }
+
+ eventStatus->iItemsLeft = newCount;
+ }
+ else
+ {
+ return EFalse;
+ }
+
+ WRITELOG1( "CHarvesterEventManager::DecreaseItemCountL() iItemsLeft = %d", eventStatus->iItemsLeft );
+
+ // send finished event to all matching observers
+ if ( eventStatus->iItemsLeft <= 0 )
+ {
+ eventStatus->iItemsLeft = 0;
+ eventStatus->iCurrentState = EHEStateFinished;
+
+ // EHEObserverTypeOverall state is handled directly in harvesterao during harvesting
+ if( aHEObserverType != EHEObserverTypeOverall )
+ {
+ const TInt err = SendEventL( aHEObserverType, eventStatus->iCurrentState, eventStatus->iItemsLeft );
+ return err == KErrNone;
+ }
+ }
+
+ // still harvesting
+ eventStatus->iCurrentState = EHEStateHarvesting;
+
+ // send harvesting event to all matching observers
+ TBool wasSent = EFalse;
+ TInt count = iRegisteredObservers.Count();
+ for ( TInt i = count; --i >= 0; )
+ {
+ THarvesterEventObserverInfo& observer = *(iRegisteredObservers[i]);
+
+ if( CheckObserverType( observer.iObserverType, aHEObserverType ) )
+ {
+ observer.iDelta += aCount;
+
+ // observers interval full
+ if ( observer.iDelta >= observer.iNotificationInterval )
+ {
+ TInt err = SendSingleEvent( observer, aHEObserverType,
+ eventStatus->iCurrentState, eventStatus->iItemsLeft );
+ if ( err == KErrNone )
+ {
+ wasSent = ETrue;
+ }
+ }
+ }
+ }
+
+ return wasSent;
+ }
+
+TInt CHarvesterEventManager::SendSingleEvent(
+ THarvesterEventObserverInfo& aEventObserverInfo,
+ HarvesterEventObserverType aObserverType,
+ HarvesterEventState aEventState, TUint aItemsLeft )
+ {
+ aEventObserverInfo.iDelta = 0;
+
+ THarvesterEventNotification notification;
+ notification.iObserverId = aEventObserverInfo.iObserverId;
+ notification.iObserverType = aObserverType;
+ notification.iCurrentState = aEventState;
+ notification.iItemsLeft = aItemsLeft;
+
+ THarvesterEventQueue& eventQueue = *(aEventObserverInfo.iQueuePtr);
+ TInt err = eventQueue.Send( notification );
+ return err;
+ }
+
+EXPORT_C TUint CHarvesterEventManager::ItemCount(
+ HarvesterEventObserverType aHEObserverType )
+ {
+ TEventStatus* eventStatus = GetEventStatus( aHEObserverType );
+ if( eventStatus )
+ {
+ return eventStatus->iItemsLeft;
+ }
+
+ return 0;
+ }
+
+EXPORT_C TInt CHarvesterEventManager::SendEventL(
+ HarvesterEventObserverType aHEObserverType,
+ HarvesterEventState aHEState, TUint aItemsLeft )
+ {
+ TEventStatus* eventStatus = GetEventStatus( aHEObserverType );
+ if( eventStatus )
+ {
+ eventStatus->iCurrentState = aHEState;
+ }
+
+ THarvesterEventNotification notification;
+ notification.iObserverType = aHEObserverType;
+ notification.iCurrentState = aHEState;
+ notification.iItemsLeft = aItemsLeft;
+
+ TInt err = KErrNone;
+ TInt count = iRegisteredObservers.Count();
+ for ( TInt i = count; --i >= 0; )
+ {
+ THarvesterEventObserverInfo& observer = *(iRegisteredObservers[i]);
+
+ if( CheckObserverType( observer.iObserverType, aHEObserverType ) )
+ {
+ notification.iObserverId = observer.iObserverId;
+
+ THarvesterEventQueue& eventQueue = *(observer.iQueuePtr);
+ TInt sendErr = eventQueue.Send( notification );
+ // Take first error
+ if( err == KErrNone )
+ {
+ err = sendErr;
+ }
+ }
+ }
+ return err;
+ }
+
+EXPORT_C void CHarvesterEventManager::RegisterEventObserverL( const RMessage2& aMessage )
+ {
+ THarvesterEventObserverInfo* observerInfo = new (ELeave) THarvesterEventObserverInfo;
+ CleanupStack::PushL( observerInfo );
+
+ TPckg<THarvesterEventObserverInfo> pckgObserverInfo( *observerInfo );
+ TInt err = aMessage.Read( 0, pckgObserverInfo );
+
+ // Init server side values
+ observerInfo->iQueuePtr = NULL;
+ observerInfo->iDelta = 0;
+ observerInfo->iProcessUid = aMessage.Identity().iUid;
+
+ // Check if observer ID is not yet used
+ // and if event queue already exists
+ TBool found = EFalse;
+ for(TInt i = iRegisteredObservers.Count(); --i >= 0;)
+ {
+ THarvesterEventObserverInfo* info = iRegisteredObservers[i];
+ if( info->iProcessUid == observerInfo->iProcessUid &&
+ info->iQueueHandle == observerInfo->iQueueHandle )
+ {
+ if( info->iObserverId == observerInfo->iObserverId )
+ {
+ User::Leave( KErrAlreadyExists );
+ }
+
+ observerInfo->iQueuePtr = info->iQueuePtr;
+ found = ETrue;
+ }
+ }
+
+ // create new event queue if no match was found
+ if ( !found )
+ {
+ THarvesterEventQueue* msgQueue = new (ELeave) THarvesterEventQueue;
+ CleanupStack::PushL( msgQueue );
+
+ TInt err = msgQueue->Open( aMessage, 1 );
+
+ User::LeaveIfError( err );
+
+ iEventQueues.AppendL( msgQueue );
+ observerInfo->iQueuePtr = msgQueue;
+
+ CleanupStack::Pop( msgQueue );
+ }
+
+ iRegisteredObservers.AppendL( observerInfo );
+
+ CleanupStack::Pop( observerInfo );
+
+ // send event if register is coming in the middle of harvesting
+ for( TInt i = iEventStatuses.Count(); --i >= 0; )
+ {
+ TEventStatus& eventStatus = iEventStatuses[i];
+ if( CheckObserverType( observerInfo->iObserverType,
+ eventStatus.iObserverType) )
+ {
+ if( eventStatus.iItemsLeft > 0 )
+ {
+ TRAP_IGNORE( SendEventL( eventStatus.iObserverType,
+ eventStatus.iCurrentState, eventStatus.iItemsLeft ) );
+ }
+ }
+ }
+ }
+
+EXPORT_C TInt CHarvesterEventManager::UnregisterEventObserver( const RMessage2& aMessage )
+ {
+ TUint observerId = (TUint)aMessage.Int0();
+ TInt queueHandle = aMessage.Int1();
+
+ TInt serverQueueHandle = KNullHandle;
+ TUint processUid = aMessage.Identity().iUid;
+
+ TBool otherObserverFound = EFalse;
+ for(TInt i = iRegisteredObservers.Count(); --i >= 0;)
+ {
+ THarvesterEventObserverInfo* observer = iRegisteredObservers[i];
+ if( observer->iProcessUid == processUid &&
+ observer->iQueueHandle == queueHandle )
+ {
+ // Remove registered observer
+ if( observer->iObserverId == observerId )
+ {
+ serverQueueHandle = observer->iQueuePtr->Handle();
+
+ iRegisteredObservers.Remove( i );
+ delete observer;
+ }
+ // Find if any other observer is using the same queue
+ else
+ {
+ otherObserverFound = ETrue;
+ }
+ }
+ }
+
+ if( serverQueueHandle )
+ {
+ // Remove the queue if removed observer
+ // was the last observer which used it
+ if( !otherObserverFound )
+ {
+ for(TInt i = iEventQueues.Count(); --i >= 0;)
+ {
+ THarvesterEventQueue* queue = iEventQueues[i];
+ if( queue->Handle() == serverQueueHandle )
+ {
+ iEventQueues.Remove( i );
+ queue->Close();
+ delete queue;
+ break;
+ }
+ }
+ }
+
+ return KErrNone;
+ }
+ else
+ {
+ return KErrNotFound;
+ }
+ }
+
+EXPORT_C HarvesterEventState CHarvesterEventManager::CurrentState(
+ HarvesterEventObserverType aHEObserverType )
+ {
+ TInt count = iEventStatuses.Count();
+ for( TInt i = count; --i >= 0; )
+ {
+ TEventStatus& eventStatus = iEventStatuses[i];
+ if( eventStatus.iObserverType == aHEObserverType )
+ {
+ return eventStatus.iCurrentState;
+ }
+ }
+ return EHEStateUninitialized;
+ }
+
+TBool CHarvesterEventManager::CheckObserverType( TInt aObserverType, TInt aEventType )
+ {
+ return aObserverType & aEventType;
+ }
+
+CHarvesterEventManager::TEventStatus* CHarvesterEventManager::GetEventStatus(
+ HarvesterEventObserverType aHEObserverType )
+ {
+ TInt count = iEventStatuses.Count();
+ for(TInt i = count; --i >= 0; )
+ {
+ TEventStatus& eventStatus = iEventStatuses[i];
+ if( eventStatus.iObserverType == aHEObserverType )
+ {
+ return &eventStatus;
+ }
+ }
+
+ return NULL;
+ }
+
+EXPORT_C TUint CHarvesterEventManager::GetLastClientId()
+ {
+ // deprecated method, just return something
+ return 0;
+ }