harvester/common/src/harvestereventmanager.cpp
changeset 0 c53acadfccc6
child 8 6752808b2036
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15  *
       
    16 */
       
    17 #include <e32svr.h>
       
    18 
       
    19 #include "harvestereventmanager.h"
       
    20 #include "harvesterlog.h"
       
    21 
       
    22 const TInt KHarvesterEventManagerTLSKey = 0x200104D9;
       
    23 
       
    24 CHarvesterEventManager::CHarvesterEventManager()
       
    25 	{
       
    26 	}
       
    27 
       
    28 void CHarvesterEventManager::ConstructL()
       
    29 	{
       
    30 	}
       
    31 
       
    32 CHarvesterEventManager::~CHarvesterEventManager()
       
    33 	{
       
    34 	for ( TInt i = 0; i < iEventQueues.Count(); i++)
       
    35 		{
       
    36 		iEventQueues[i]->Close();
       
    37 		}
       
    38 	iEventQueues.ResetAndDestroy();
       
    39 	iEventQueues.Close();
       
    40 	
       
    41 	iRegisteredObservers.ResetAndDestroy();
       
    42 	iRegisteredObservers.Close();
       
    43 	
       
    44 	iEventStatuses.Close();
       
    45 	}
       
    46 
       
    47 EXPORT_C CHarvesterEventManager* CHarvesterEventManager::GetInstanceL()
       
    48 	{
       
    49 	WRITELOG( "CHarvesterEventManager::GetInstanceL" );
       
    50 
       
    51 	CHarvesterEventManagerStaticData* data = 
       
    52 		static_cast<CHarvesterEventManagerStaticData*>( 
       
    53 				UserSvr::DllTls( KHarvesterEventManagerTLSKey ) );
       
    54 
       
    55 	CHarvesterEventManager* instance = NULL;
       
    56 
       
    57 	if ( !data )
       
    58         {
       
    59         instance = new (ELeave) CHarvesterEventManager();
       
    60         CleanupStack::PushL( instance );
       
    61         instance->ConstructL();
       
    62         UserSvr::DllSetTls( KHarvesterEventManagerTLSKey,
       
    63         	new (ELeave) CHarvesterEventManagerStaticData(instance) );
       
    64         CleanupStack::Pop( instance );
       
    65         }
       
    66     else
       
    67         {
       
    68         instance = data->iHEM;
       
    69         data->iRefCount++;
       
    70         }
       
    71 
       
    72     return instance;
       
    73 	}
       
    74 
       
    75 EXPORT_C void CHarvesterEventManager::ReleaseInstance()
       
    76     {
       
    77     WRITELOG( "CHarvesterEventManager::ReleaseInstance" );
       
    78     CHarvesterEventManagerStaticData* data =
       
    79         static_cast<CHarvesterEventManagerStaticData*>( 
       
    80         		UserSvr::DllTls( KHarvesterEventManagerTLSKey ) );
       
    81     if ( data )
       
    82         {
       
    83         data->iRefCount--;
       
    84         if ( data->iRefCount <= 0 )
       
    85             {
       
    86             // destroy the singleton and free TLS
       
    87             delete data;
       
    88             UserSvr::DllFreeTls( KHarvesterEventManagerTLSKey );
       
    89             }
       
    90         }
       
    91     }
       
    92 
       
    93 EXPORT_C void CHarvesterEventManager::IncreaseItemCount( 
       
    94 		HarvesterEventObserverType aHEObserverType, TUint aCount )
       
    95 	{
       
    96 	TEventStatus* eventStatus = GetEventStatus( aHEObserverType );
       
    97 	WRITELOG2( "CHarvesterEventManager::IncreaseItemCount(%d) type = %d", aCount, aHEObserverType); 
       
    98 	
       
    99 #ifdef _DEBUG
       
   100 	switch(aHEObserverType)
       
   101 	    {
       
   102 	    case EHEObserverTypePlaceholder:
       
   103 	        WRITELOG( "CHarvesterEventManager::IncreaseItemCount() EHEObserverTypePlaceholder");
       
   104 	        break;
       
   105 	    case EHEObserverTypeMMC:
       
   106 	        WRITELOG( "CHarvesterEventManager::IncreaseItemCount() EHEObserverTypeMMC");
       
   107 	        break;
       
   108 	    case EHEObserverTypeOverall:
       
   109 	        WRITELOG( "CHarvesterEventManager::IncreaseItemCount() EHEObserverTypeOverall");
       
   110 	        break;
       
   111 	    default:
       
   112 	        WRITELOG( "CHarvesterEventManager::IncreaseItemCount() Unknown type!");
       
   113 	    };
       
   114 #endif
       
   115 	
       
   116 	if( eventStatus )
       
   117 		{
       
   118 		WRITELOG1( "CHarvesterEventManager::IncreaseItemCount() itemsleft = %d old ", eventStatus->iItemsLeft);
       
   119 		eventStatus->iItemsLeft += aCount;
       
   120 		WRITELOG1( "CHarvesterEventManager::IncreaseItemCount() itemsleft = %d ", eventStatus->iItemsLeft);
       
   121 		}
       
   122 	else
       
   123 		{
       
   124 		TEventStatus eventStatus;
       
   125 		eventStatus.iCurrentState = EHEStateStarted;
       
   126 		WRITELOG1( "CHarvesterEventManager::IncreaseItemCount() itemsleft = %d old", aCount);
       
   127 		eventStatus.iItemsLeft = aCount;
       
   128 		WRITELOG1( "CHarvesterEventManager::IncreaseItemCount() itemsleft = %d ", aCount);
       
   129 		eventStatus.iObserverType = aHEObserverType;
       
   130 		iEventStatuses.Append( eventStatus );
       
   131 		}
       
   132 	}
       
   133 
       
   134 EXPORT_C TBool CHarvesterEventManager::DecreaseItemCountL( 
       
   135 		HarvesterEventObserverType aHEObserverType, TUint aCount )
       
   136 	{
       
   137 	TEventStatus* eventStatus = GetEventStatus( aHEObserverType );
       
   138 	WRITELOG2( "CHarvesterEventManager::DecreaseItemCountL(%d) type = %d ", aCount, aHEObserverType);
       
   139 	
       
   140 #ifdef _DEBUG
       
   141     switch(aHEObserverType)
       
   142         {
       
   143         case EHEObserverTypePlaceholder:
       
   144             WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypePlaceholder");
       
   145             break;
       
   146         case EHEObserverTypeMMC:
       
   147             WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypeMMC");
       
   148             break;
       
   149         case EHEObserverTypeOverall:
       
   150             WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() EHEObserverTypeOverall");
       
   151             break;
       
   152         default:
       
   153             WRITELOG( "CHarvesterEventManager::DecreaseItemCountL() Unknown type!");
       
   154         };
       
   155 #endif
       
   156 	
       
   157 	if( eventStatus )
       
   158 		{
       
   159 		WRITELOG1( "CHarvesterEventManager::DecreaseItemCountL() iItemsLeft = %d old", eventStatus->iItemsLeft);
       
   160 		TUint newCount = eventStatus->iItemsLeft - aCount;
       
   161 
       
   162 		// check for wrap
       
   163 		if( newCount > eventStatus->iItemsLeft )
       
   164 			{
       
   165 			newCount = 0;
       
   166 			}
       
   167 
       
   168 		// event doesn't need to be sent, if count hasn't changed 
       
   169 		if( newCount == eventStatus->iItemsLeft )
       
   170 			{
       
   171 			return EFalse;
       
   172 			}
       
   173 
       
   174 		eventStatus->iItemsLeft = newCount;
       
   175 		}
       
   176 	else
       
   177 		{
       
   178 		return EFalse;
       
   179 		}
       
   180 
       
   181 	WRITELOG1( "CHarvesterEventManager::DecreaseItemCountL() iItemsLeft = %d", eventStatus->iItemsLeft );
       
   182 	
       
   183 	// send finished event to all matching observers
       
   184 	if ( eventStatus->iItemsLeft <= 0 )
       
   185 		{
       
   186 		eventStatus->iItemsLeft = 0;
       
   187 		eventStatus->iCurrentState = EHEStateFinished;
       
   188 
       
   189 		// EHEObserverTypeOverall state is handled directly in harvesterao during harvesting
       
   190         if( aHEObserverType != EHEObserverTypeOverall )
       
   191 		    {
       
   192 		    const TInt err = SendEventL( aHEObserverType, eventStatus->iCurrentState, eventStatus->iItemsLeft );
       
   193 		    return err == KErrNone;
       
   194 		    }
       
   195 		}
       
   196 
       
   197 	// still harvesting
       
   198 	eventStatus->iCurrentState = EHEStateHarvesting;
       
   199 	
       
   200 	// send harvesting event to all matching observers
       
   201 	TBool wasSent = EFalse;
       
   202 	TInt count = iRegisteredObservers.Count();
       
   203 	for ( TInt i = count; --i >= 0; )
       
   204 		{
       
   205 		THarvesterEventObserverInfo& observer = *(iRegisteredObservers[i]);
       
   206 
       
   207 		if( CheckObserverType( observer.iObserverType, aHEObserverType ) )
       
   208 			{
       
   209 			observer.iDelta += aCount;
       
   210 
       
   211 			// observers interval full
       
   212 			if ( observer.iDelta >= observer.iNotificationInterval )
       
   213 				{
       
   214 				TInt err = SendSingleEvent( observer, aHEObserverType, 
       
   215 						eventStatus->iCurrentState, eventStatus->iItemsLeft );
       
   216 				if ( err == KErrNone )
       
   217 					{
       
   218 					wasSent = ETrue;
       
   219 					}
       
   220 				}
       
   221 			}
       
   222 		}
       
   223 
       
   224 	return wasSent;
       
   225 	}
       
   226 
       
   227 TInt CHarvesterEventManager::SendSingleEvent( 
       
   228 		THarvesterEventObserverInfo& aEventObserverInfo, 
       
   229 		HarvesterEventObserverType aObserverType, 
       
   230 		HarvesterEventState aEventState, TUint aItemsLeft )
       
   231 	{
       
   232 	aEventObserverInfo.iDelta = 0;
       
   233 
       
   234 	THarvesterEventNotification notification;
       
   235 	notification.iObserverId = aEventObserverInfo.iObserverId;
       
   236 	notification.iObserverType = aObserverType;
       
   237 	notification.iCurrentState = aEventState;
       
   238 	notification.iItemsLeft = aItemsLeft;
       
   239 
       
   240 	THarvesterEventQueue& eventQueue = *(aEventObserverInfo.iQueuePtr);
       
   241 	TInt err = eventQueue.Send( notification );
       
   242 	return err;
       
   243 	}
       
   244 
       
   245 EXPORT_C TUint CHarvesterEventManager::ItemCount( 
       
   246 		HarvesterEventObserverType aHEObserverType )
       
   247 	{
       
   248 	TEventStatus* eventStatus = GetEventStatus( aHEObserverType );
       
   249 	if( eventStatus )
       
   250 		{
       
   251 		return eventStatus->iItemsLeft;
       
   252 		}
       
   253 	
       
   254 	return 0;
       
   255 	}
       
   256 
       
   257 EXPORT_C TInt CHarvesterEventManager::SendEventL( 
       
   258 		HarvesterEventObserverType aHEObserverType,
       
   259 		HarvesterEventState aHEState, TUint aItemsLeft )
       
   260 	{
       
   261 	TEventStatus* eventStatus = GetEventStatus( aHEObserverType );
       
   262 	if( eventStatus )
       
   263 		{
       
   264 		eventStatus->iCurrentState = aHEState;
       
   265 		}
       
   266 
       
   267 	THarvesterEventNotification notification;
       
   268 	notification.iObserverType = aHEObserverType;
       
   269 	notification.iCurrentState = aHEState;
       
   270 	notification.iItemsLeft = aItemsLeft;
       
   271 
       
   272 	TInt err = KErrNone;
       
   273 	TInt count = iRegisteredObservers.Count();
       
   274 	for ( TInt i = count; --i >= 0; )
       
   275 		{
       
   276 		THarvesterEventObserverInfo& observer = *(iRegisteredObservers[i]);
       
   277 
       
   278 		if( CheckObserverType( observer.iObserverType, aHEObserverType ) )
       
   279 			{
       
   280 			notification.iObserverId = observer.iObserverId;
       
   281 
       
   282 			THarvesterEventQueue& eventQueue = *(observer.iQueuePtr);
       
   283 			TInt sendErr = eventQueue.Send( notification );
       
   284 			// Take first error
       
   285 			if( err == KErrNone )
       
   286 				{
       
   287 				err = sendErr;
       
   288 				}
       
   289 			}
       
   290 		}
       
   291 	return err;
       
   292 	}
       
   293 
       
   294 EXPORT_C void CHarvesterEventManager::RegisterEventObserverL( const RMessage2& aMessage )
       
   295 	{
       
   296 	THarvesterEventObserverInfo* observerInfo = new (ELeave) THarvesterEventObserverInfo;
       
   297 	CleanupStack::PushL( observerInfo );
       
   298 
       
   299     TPckg<THarvesterEventObserverInfo> pckgObserverInfo( *observerInfo );
       
   300     TInt err = aMessage.Read( 0, pckgObserverInfo );
       
   301 
       
   302     // Init server side values
       
   303     observerInfo->iQueuePtr = NULL;
       
   304     observerInfo->iDelta = 0;
       
   305     observerInfo->iProcessUid = aMessage.Identity().iUid;
       
   306 
       
   307     // Check if observer ID is not yet used
       
   308     // and if event queue already exists
       
   309     TBool found = EFalse;
       
   310 	for(TInt i = iRegisteredObservers.Count(); --i >= 0;)
       
   311 		{
       
   312 		THarvesterEventObserverInfo* info = iRegisteredObservers[i];
       
   313 		if( info->iProcessUid == observerInfo->iProcessUid && 
       
   314 			info->iQueueHandle == observerInfo->iQueueHandle )
       
   315 			{
       
   316 			if( info->iObserverId == observerInfo->iObserverId )
       
   317 				{
       
   318 				User::Leave( KErrAlreadyExists );
       
   319 				}
       
   320 
       
   321 			observerInfo->iQueuePtr = info->iQueuePtr;
       
   322 			found = ETrue;
       
   323 			}
       
   324 		}
       
   325 
       
   326 	// create new event queue if no match was found 
       
   327 	if ( !found )
       
   328 		{
       
   329 		THarvesterEventQueue* msgQueue = new (ELeave) THarvesterEventQueue;
       
   330 		CleanupStack::PushL( msgQueue );
       
   331 
       
   332 		TInt err = msgQueue->Open( aMessage, 1 );
       
   333 
       
   334 		User::LeaveIfError( err );
       
   335 
       
   336 		iEventQueues.AppendL( msgQueue );
       
   337 		observerInfo->iQueuePtr = msgQueue;
       
   338 		
       
   339 		CleanupStack::Pop( msgQueue );
       
   340 		}	
       
   341 
       
   342 	iRegisteredObservers.AppendL( observerInfo );
       
   343 
       
   344 	CleanupStack::Pop( observerInfo );
       
   345 	
       
   346 	// send event if register is coming in the middle of harvesting
       
   347 	for( TInt i = iEventStatuses.Count(); --i >= 0; )
       
   348 		{
       
   349 		TEventStatus& eventStatus = iEventStatuses[i];
       
   350 		if( CheckObserverType( observerInfo->iObserverType, 
       
   351 				eventStatus.iObserverType) )
       
   352 			{
       
   353 			if( eventStatus.iItemsLeft > 0 )
       
   354 				{
       
   355 				TRAP_IGNORE( SendEventL( eventStatus.iObserverType, 
       
   356 						eventStatus.iCurrentState, eventStatus.iItemsLeft ) );
       
   357 				}
       
   358 			}
       
   359 		}
       
   360 	}
       
   361 
       
   362 EXPORT_C TInt CHarvesterEventManager::UnregisterEventObserver( const RMessage2& aMessage )
       
   363 	{
       
   364 	TUint observerId = (TUint)aMessage.Int0();
       
   365 	TInt queueHandle = aMessage.Int1();
       
   366 
       
   367 	TInt serverQueueHandle = KNullHandle;
       
   368 	TUint processUid = aMessage.Identity().iUid;
       
   369 	
       
   370 	TBool otherObserverFound = EFalse;
       
   371 	for(TInt i = iRegisteredObservers.Count(); --i >= 0;)
       
   372 		{
       
   373 		THarvesterEventObserverInfo* observer = iRegisteredObservers[i];
       
   374 		if( observer->iProcessUid == processUid && 
       
   375 			observer->iQueueHandle == queueHandle )
       
   376 			{
       
   377 			// Remove registered observer
       
   378 			if( observer->iObserverId == observerId )
       
   379 				{
       
   380 				serverQueueHandle = observer->iQueuePtr->Handle();
       
   381 				
       
   382 				iRegisteredObservers.Remove( i );
       
   383 				delete observer;
       
   384 				}
       
   385 			// Find if any other observer is using the same queue
       
   386 			else
       
   387 				{
       
   388 				otherObserverFound = ETrue;
       
   389 				}
       
   390 			}
       
   391 		}
       
   392 
       
   393 	if( serverQueueHandle )
       
   394 		{
       
   395 		// Remove the queue if removed observer 
       
   396 		// was the last observer which used it
       
   397 		if( !otherObserverFound )
       
   398 			{
       
   399 			for(TInt i = iEventQueues.Count(); --i >= 0;)
       
   400 				{
       
   401 				THarvesterEventQueue* queue = iEventQueues[i];
       
   402 				if( queue->Handle() == serverQueueHandle )
       
   403 					{
       
   404 					iEventQueues.Remove( i );
       
   405 					queue->Close();
       
   406 					delete queue;
       
   407 					break;
       
   408 					}
       
   409 				}
       
   410 			}
       
   411 
       
   412 		return KErrNone;
       
   413 		}
       
   414 	else
       
   415 		{
       
   416 		return KErrNotFound;
       
   417 		}
       
   418 	}
       
   419 
       
   420 EXPORT_C HarvesterEventState CHarvesterEventManager::CurrentState( 
       
   421 		HarvesterEventObserverType aHEObserverType )
       
   422 	{
       
   423 	TInt count = iEventStatuses.Count();
       
   424 	for( TInt i = count; --i >= 0; )
       
   425 		{
       
   426 		TEventStatus& eventStatus = iEventStatuses[i];
       
   427 		if( eventStatus.iObserverType == aHEObserverType )
       
   428 			{
       
   429 			return eventStatus.iCurrentState;
       
   430 			}
       
   431 		}
       
   432 	return EHEStateUninitialized;
       
   433 	}
       
   434 
       
   435 TBool CHarvesterEventManager::CheckObserverType( TInt aObserverType, TInt aEventType )
       
   436 	{
       
   437 	return aObserverType & aEventType;
       
   438 	}
       
   439 
       
   440 CHarvesterEventManager::TEventStatus* CHarvesterEventManager::GetEventStatus( 
       
   441 		HarvesterEventObserverType aHEObserverType )
       
   442 	{
       
   443 	TInt count = iEventStatuses.Count();
       
   444 	for(TInt i = count; --i >= 0; )
       
   445 		{
       
   446 		TEventStatus& eventStatus = iEventStatuses[i];
       
   447 		if( eventStatus.iObserverType == aHEObserverType )
       
   448 			{
       
   449 			return &eventStatus;
       
   450 			}
       
   451 		}
       
   452 
       
   453 	return NULL;
       
   454 	}
       
   455 
       
   456 EXPORT_C TUint CHarvesterEventManager::GetLastClientId()
       
   457 	{
       
   458 	// deprecated method, just return something
       
   459 	return 0;
       
   460 	}