phonebookengines/contactsmodel/cntsrv/src/CCntEventQueue.cpp
changeset 0 e686773b3f54
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntsrv/src/CCntEventQueue.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,178 @@
+// Copyright (c) 2005-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:
+//
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+
+#include "CCntEventQueue.h"
+#include "CCntServer.h"
+#include "CCntLogger.h"
+
+
+extern void DebugLogNotification(const TDesC& aMethod, const TContactDbObserverEvent &aEvent);
+
+
+CEventQueue::CEventQueue()
+	: iEvents(KCntEventGranularity)
+	{
+	}
+
+
+CEventQueue::~CEventQueue()
+	{
+	iEvents.Close();
+	}
+
+
+void CEventQueue::QueueEvent(const TContactDbObserverEvent &aEvent)
+	{
+	// Flush the queue - there's no point in sending out all the preceeding
+	// events when the an Unknown Changes event is being sent.
+	// Unknown changes means that there are too many events to propagate and
+	// the client should resync all its cached data.
+	if (aEvent.iType == EContactDbObserverEventUnknownChanges)
+		{
+		Flush();	
+		}
+	
+	// Is the queue in order, if not then return (no event will be sent)
+	if (Flag(EQueueError))
+		{
+		return;	
+		}
+		
+	// Can we send the event right away, i.e. do we have an outstanding request
+	if (Flag(EValidEventMsg))
+		{
+		SendEvent(aEvent);	
+		}// Is the queue full? If so set flag EQueueError and return
+	else if (iEvents.Count() > KMaxNumberOfEventsInEventQueue)
+		{
+		
+		DEBUG_PRINTDN2(__VERBOSE_DEBUG__,_L("[CNTMODEL] ->X"), aEvent);
+
+		Flush();
+		SetFlag(EQueueError);
+		}// Otherwise can we add the request to the queue
+	else if (iEvents.Append(aEvent)!=KErrNone)
+		{
+		SetFlag(EQueueError);
+		}
+#if defined(__VERBOSE_DEBUG__)	
+	else
+		{
+		// If added then add it to log
+		DebugLogNotification(_L("[CNTMODEL] ->Q"), aEvent);	
+		}
+#endif
+	}
+
+
+void CEventQueue::Flush()
+	{
+	iEvents.Reset();	
+	}
+
+
+void CEventQueue::RequestEvent(const RMessage2& aMessage)
+	{
+	__ASSERT_DEBUG(!Flag(EValidEventMsg),User::Leave(KErrCompletion));
+	if (!Flag(EValidEventMsg))
+		{
+		iEventMsg=aMessage;
+		SetFlag(EValidEventMsg);
+		if (Flag(EQueueError))
+			{
+			TContactDbObserverEvent errorEvent;
+			//EContactDbObserverEventUnknownChanges is indicating that the event queue is full
+			errorEvent.iType = EContactDbObserverEventUnknownChanges;
+			errorEvent.iContactId = KNullContactId;
+			errorEvent.iConnectionId = KCntNullConnectionId;
+			ClearFlag(EQueueError);
+			SendEvent(errorEvent);
+			}
+		else if (iEvents.Count()>0)
+			{
+			SendEvent(iEvents[0]);
+			iEvents.Remove(0);
+			}
+		else
+			{
+			//No events has happened, so there is nothing to tell the client,
+			//But to be able to test the API policing we will complete the message
+			//if it contains the ApiPolicingTest flag and that the message is sent by the 
+			//API policing test process sid(0x101F7784)
+			TInt isApiPolicingTest = aMessage.Int1();
+			if (isApiPolicingTest == 666 && aMessage.SecureId() == 0x101F7784)
+				{
+				TContactDbObserverEvent nullEvent;
+				nullEvent.iType = EContactDbObserverEventNull;
+				nullEvent.iConnectionId = 0;
+				SendEvent(nullEvent);				
+				}
+			}
+		}
+	}
+
+
+void CEventQueue::CancelEventRequest()
+	{
+	if (Flag(EValidEventMsg))
+		{
+		iEventMsg.Complete(KErrCancel);
+		ClearFlag(EValidEventMsg);
+		}
+	}
+
+
+void CEventQueue::SendEvent(const TContactDbObserverEvent &aEvent)
+	{
+     DEBUG_PRINTDN2(__VERBOSE_DEBUG__,_L("[CNTMODEL] Q->"), aEvent);
+
+	TPckgC<TContactDbObserverEvent> event(aEvent);
+	TInt err = iEventMsg.Write(0, event);
+	if (err != KErrNone)
+		{
+		// If there is an error caused, for example, by the client dying, just log the error code.
+		DEBUG_PRINT2(__VERBOSE_DEBUG__, _L("[CNTMODEL] iEventMsg.Write() error: %d"), err);
+ 		}
+	else
+		{
+		iEventMsg.Complete(KErrNone);
+		}
+	ClearFlag(EValidEventMsg);
+	}
+
+
+TBool CEventQueue::Flag(TFlag aFlag)
+	{
+	return iFlags&aFlag;
+	}
+
+
+void CEventQueue::SetFlag(TFlag aFlag)
+	{
+	iFlags|=aFlag;
+	}
+
+
+void CEventQueue::ClearFlag(TFlag aFlag)
+	{
+	iFlags&=(~aFlag);
+	}