diff -r 000000000000 -r c53acadfccc6 harvester/common/src/harvestereventmanager.cpp --- /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 + +#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( + 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( + 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 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; + }