harvester/client/src/harvestereventobserverao.cpp
changeset 0 c53acadfccc6
child 3 6752808b2036
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2007-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 #include <harvestereventenum.h>
       
    19 
       
    20 #include "harvestereventobserverao.h"
       
    21 #include "harvesterclient.h"
       
    22 
       
    23 const TInt KHarverterEventQueueSize = 32;
       
    24 
       
    25 CHarvesterEventObserverAO::CHarvesterEventObserverAO( 
       
    26 		RHarvesterClient& aHarvesterClient ) :
       
    27 	CActive(CActive::EPriorityStandard), // Standard priority
       
    28 	iHarvesterClient( aHarvesterClient )
       
    29 	{
       
    30 	}
       
    31 
       
    32 CHarvesterEventObserverAO* CHarvesterEventObserverAO::NewLC( 
       
    33 		RHarvesterClient& aHarvesterClient )
       
    34 	{
       
    35 	CHarvesterEventObserverAO* self = 
       
    36 		new ( ELeave ) CHarvesterEventObserverAO( aHarvesterClient );
       
    37 	CleanupStack::PushL(self);
       
    38 	self->ConstructL();
       
    39 	return self;
       
    40 	}
       
    41 
       
    42 CHarvesterEventObserverAO* CHarvesterEventObserverAO::NewL( 
       
    43 		RHarvesterClient& aHarvesterClient )
       
    44 	{
       
    45 	CHarvesterEventObserverAO* self = 
       
    46 		CHarvesterEventObserverAO::NewLC( aHarvesterClient );
       
    47 	CleanupStack::Pop( self ); // self;
       
    48 	return self;
       
    49 	}
       
    50 
       
    51 void CHarvesterEventObserverAO::ConstructL()
       
    52 	{
       
    53 	CActiveScheduler::Add( this ); // Add to scheduler
       
    54 	}
       
    55 
       
    56 CHarvesterEventObserverAO::~CHarvesterEventObserverAO()
       
    57 	{
       
    58 	Cancel(); // Cancel any request, if outstanding
       
    59 
       
    60 	for(TInt i = iObservers.Count(); --i >= 0;)
       
    61 		{
       
    62 		THarvesterEventObserver& observer = *(iObservers[i]);
       
    63 
       
    64 		TIpcArgs ipcArgs( observer.iObserverInfo.iObserverId, 
       
    65 				iHarvesterEventQueue.Handle() );
       
    66 
       
    67 		iHarvesterClient.Send( EUnregisterHarvesterEvent, ipcArgs );
       
    68 		}
       
    69 
       
    70 	iHarvesterEventQueue.Close();
       
    71 	
       
    72 	iObservers.ResetAndDestroy();
       
    73 	}
       
    74 
       
    75 void CHarvesterEventObserverAO::DoCancel()
       
    76 	{
       
    77 	iHarvesterEventQueue.CancelDataAvailable();
       
    78 	}
       
    79 
       
    80 void CHarvesterEventObserverAO::AddHarvesterEventObserverL( 
       
    81 			MHarvesterEventObserver& aHarvesterEventObserver, 
       
    82 			TInt aHEObserverType,
       
    83     		TInt aNotificationInterval )
       
    84 	{
       
    85 	RHandleBase& queueHandle = GetEventQueueHandleL();
       
    86 
       
    87 	THarvesterEventObserver* observer = 
       
    88 			new (ELeave) THarvesterEventObserver( aHarvesterEventObserver );
       
    89 	CleanupStack::PushL( observer );
       
    90 
       
    91 	// Init client side values
       
    92 	observer->iObserverInfo.iQueueHandle = queueHandle.Handle();
       
    93 	observer->iObserverInfo.iObserverId = NextObserverId();
       
    94 	observer->iObserverInfo.iObserverType = aHEObserverType;
       
    95 	observer->iObserverInfo.iNotificationInterval = aNotificationInterval;
       
    96 
       
    97 	iObservers.AppendL( observer );
       
    98 
       
    99 	CleanupStack::Pop( observer );
       
   100 
       
   101 	TPckg<THarvesterEventObserverInfo> pckgObserverInfo( observer->iObserverInfo );
       
   102 	TIpcArgs ipcArgs( &pckgObserverInfo, queueHandle );
       
   103 
       
   104 	TInt err = iHarvesterClient.SendReceive( ERegisterHarvesterEvent, ipcArgs );
       
   105 
       
   106 	User::LeaveIfError( err );
       
   107 
       
   108 	if( !IsActive() )
       
   109 		{
       
   110 		iHarvesterEventQueue.NotifyDataAvailable( iStatus );
       
   111 		SetActive(); // Tell scheduler a request is active
       
   112 		}
       
   113 	}
       
   114 
       
   115 void CHarvesterEventObserverAO::RemoveHarvesterEventObserverL( 
       
   116 		MHarvesterEventObserver& aHarvesterEventObserver )
       
   117 	{
       
   118 	// clear all observers which match to callback instance
       
   119 	for(TInt i = iObservers.Count(); --i >= 0;)
       
   120 		{
       
   121 		THarvesterEventObserver* observer = iObservers[i];
       
   122 		if( &observer->iObserver == &aHarvesterEventObserver )
       
   123 			{
       
   124 			TIpcArgs ipcArgs( observer->iObserverInfo.iObserverId, 
       
   125 							iHarvesterEventQueue.Handle() );
       
   126 			iHarvesterClient.Send( EUnregisterHarvesterEvent, ipcArgs );
       
   127 			iObservers.Remove( i );
       
   128 			delete observer;
       
   129 			}
       
   130 		}
       
   131 
       
   132 	// close event queue if all observers are removed
       
   133 	if( iObservers.Count() == 0 )
       
   134 		{
       
   135 		Cancel();
       
   136 		iHarvesterEventQueue.Close();
       
   137 		}
       
   138 	}
       
   139 
       
   140 void CHarvesterEventObserverAO::RunL()
       
   141 	{
       
   142 	User::LeaveIfError( iStatus.Int() );
       
   143 
       
   144 	THarvesterEventNotification received;
       
   145 	while( iHarvesterEventQueue.Receive( received ) != KErrUnderflow )
       
   146 		{
       
   147 		for(TInt i = iObservers.Count(); --i >= 0;)
       
   148 			{
       
   149 			THarvesterEventObserver& observer = *(iObservers[i]);
       
   150 			if( observer.iObserverInfo.iObserverId == received.iObserverId )
       
   151 				{
       
   152 				observer.iObserver.HarvestingUpdated( received.iObserverType,  
       
   153 						received.iCurrentState, received.iItemsLeft );
       
   154 				break;
       
   155 				}
       
   156 			}
       
   157 		}
       
   158 
       
   159 	if( iObservers.Count() > 0 )
       
   160 		{
       
   161 		SetActive();
       
   162 		iHarvesterEventQueue.NotifyDataAvailable( iStatus );
       
   163 		}
       
   164 	}
       
   165 
       
   166 TInt CHarvesterEventObserverAO::RunError(TInt /*aError*/)
       
   167 	{
       
   168 	return KErrNone;
       
   169 	}
       
   170 
       
   171 TUint CHarvesterEventObserverAO::NextObserverId()
       
   172 	{
       
   173 	// Sort by observer IDs
       
   174 	iObservers.Sort( TLinearOrder<THarvesterEventObserver>(
       
   175 			THarvesterEventObserver::CompareObserverIds ) );
       
   176 
       
   177 	// Find smallest unused observer ID 
       
   178 	const TUint count = iObservers.Count();
       
   179 	for( TUint i = 0; i < count; i++ )
       
   180 		{
       
   181 		// Return first free observer ID 
       
   182 		if( iObservers[i]->iObserverInfo.iObserverId != i )
       
   183 			{
       
   184 			return i;
       
   185 			}
       
   186 		}
       
   187 
       
   188 	if( count )
       
   189 	    {
       
   190 	    // No free observer ID found, so return largest observer ID + 1 
       
   191 	    return iObservers[count - 1]->iObserverInfo.iObserverId + 1;
       
   192 	    }
       
   193 	// No observer IDs assigned
       
   194 	return 0;
       
   195 	}
       
   196 
       
   197 RHandleBase& CHarvesterEventObserverAO::GetEventQueueHandleL()
       
   198 	{
       
   199 	// create new message queue
       
   200 	if( KNullHandle == iHarvesterEventQueue.Handle() )
       
   201 		{
       
   202 		TInt err = iHarvesterEventQueue.CreateGlobal( KNullDesC, KHarverterEventQueueSize );
       
   203 		User::LeaveIfError( err );
       
   204 		}
       
   205 
       
   206 	return iHarvesterEventQueue;
       
   207 	}