// 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);
}