loggingservices/eventlogger/LogServ/src/LogServDatabaseChangeTracker.cpp
changeset 0 08ec8eefde2f
child 55 44f437012c90
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loggingservices/eventlogger/LogServ/src/LogServDatabaseChangeTracker.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,222 @@
+// Copyright (c) 2002-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 "LogServDatabaseChangeTracker.h"
+#include "LogChangeDefinition.h"
+#include "LogServDatabaseTransactionInterface.h"
+#include "logservpanic.h"
+#include "LogServBackupInterface.h"
+
+// Constants
+const TInt KLogArrayGranularityObservers = 3;
+const TInt KLogArrayGranularityGlobalChanges = 2;
+
+#define UNUSED_VAR(a) a = a
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// -----> CLogServDatabaseChangeTracker (source)
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CLogServDatabaseChangeTracker::CLogServDatabaseChangeTracker(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, TInt aPriority)
+:	CActive(aPriority), iDatabase(aDatabase), iBackupInterface(aBackupInterface), iObservers(KLogArrayGranularityObservers), iGlobalChanges(KLogArrayGranularityGlobalChanges)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CLogServDatabaseChangeTracker::~CLogServDatabaseChangeTracker()
+	{
+	Cancel();
+	//
+	iBackupInterface.BIObserverRemove(*this);
+	iNotifier.Close();
+	iObservers.Close();
+	iGlobalChanges.Close();
+	//
+	delete iIdler;
+	delete iChanges;
+	}
+
+void CLogServDatabaseChangeTracker::ConstructL()
+	{
+	iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectChangeTracker);
+	iChanges = CLogChangeDefinition::NewL();
+	//
+	const TInt error = iNotifier.Open(iDatabase.DTIDatabase());
+	User::LeaveIfError(error);
+	//
+	Request();
+	//
+	iIdler = CIdle::NewL(CActive::EPriorityIdle);
+	}
+
+CLogServDatabaseChangeTracker* CLogServDatabaseChangeTracker::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, TInt aPriority)
+	{
+	CLogServDatabaseChangeTracker* self = new(ELeave) CLogServDatabaseChangeTracker(aDatabase, aBackupInterface, aPriority);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServDatabaseChangeTracker::DCISubmitChangedEventContextL(TLogDatabaseChangeType aType, TLogId aEventId)
+	{
+	__ASSERT_DEBUG(aType != ELogChangeTypeUndefined, Panic(ELogUnrecognizedChangeType2));
+	iChanges->AddL(aEventId, aType, KErrGeneral);
+	}
+
+void CLogServDatabaseChangeTracker::DCISubmitGlobalChangeContextL(TUid aChangeType, TInt aContextParam1, TInt aContextParam2, TInt aContextParam3)
+	{
+	const TLogServDatabaseChangeDefinition item(aChangeType, aContextParam1, aContextParam2, aContextParam3);
+	User::LeaveIfError(iGlobalChanges.Append(item));
+	//
+	iIdler->Cancel();
+	iIdler->Start(TCallBack(IdleNotifyGlobalChangeEvents, this));
+	}
+
+void CLogServDatabaseChangeTracker::DCIRequestChangeNotificationsL(MLogServDatabaseChangeObserver& aObserver)
+	{
+	const TInt error = iObservers.InsertInAddressOrder(&aObserver);
+	User::LeaveIfError(error);
+	}
+
+void CLogServDatabaseChangeTracker::DCIRequestChangeNotificationsCancel(MLogServDatabaseChangeObserver& aObserver)
+	{
+	const TInt error = iObservers.FindInAddressOrder(&aObserver);
+	if	(error >= KErrNone)
+		iObservers.Remove(error);
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServDatabaseChangeTracker::BOHandleEventL(TLogServBackupEvent aEvent)
+	{
+	switch(aEvent)
+		{
+	case EBackupStarting:
+		{
+		Cancel();
+		iNotifier.Close();
+		break;
+		}
+	case EBackupEnded:
+		{
+		const TInt error = iNotifier.Open(iDatabase.DTIDatabase());
+		User::LeaveIfError(error);
+		Request();
+		break;
+		}
+	default:
+		__ASSERT_DEBUG(EFalse, User::Invariant());
+		break;
+		}
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServDatabaseChangeTracker::RunL()
+	{
+	// We are only interested if a commit has occurred
+	const TInt completionCode = iStatus.Int();
+	if	(completionCode == RDbNotifier::ECommit)
+		{
+		LOGTEXT("CLogServDatabaseChangeTracker::RunL() - database commit");
+
+		// Notify all observers
+		NotifyObserversL();
+
+		// Reset changes
+		iChanges->Reset();
+		}
+	Request();
+	}
+
+void CLogServDatabaseChangeTracker::DoCancel()
+	{
+	iNotifier.Cancel();
+	}
+
+TInt CLogServDatabaseChangeTracker::RunError(TInt /*aError*/)
+	{
+	// Ignore errors such as leaves from notifying observers
+	Request();
+	return KErrNone;
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServDatabaseChangeTracker::Request()
+	{
+	iNotifier.NotifyChange(iStatus);
+	SetActive();
+	}
+
+void CLogServDatabaseChangeTracker::NotifyObserversL()
+	{
+	LOGTEXT("CLogServDatabaseChangeTracker::NotifyObserversL()");
+	//
+	const TInt count = iObservers.Count();
+	for(TInt i=0; i<count; i++)
+		{
+		MLogServDatabaseChangeObserver* observer = iObservers[i];
+		observer->DCOHandleChangeEventsL(*iChanges);
+		}
+
+	// Reduce memory usage
+	iChanges->Reset();
+	//
+	LOGTEXT("CLogServDatabaseChangeTracker::NotifyObserversL() - end");
+	}
+
+void CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL()
+	{
+	LOGTEXT("CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL()");
+	//
+	const TInt count = iGlobalChanges.Count();
+	for(TInt i=0; i<count; i++)
+		{
+		const TLogServDatabaseChangeDefinition& change = iGlobalChanges[i];
+		//
+		const TInt observerCount = iObservers.Count();
+		for(TInt j=0; j<observerCount; j++)
+			{
+			MLogServDatabaseChangeObserver* observer = iObservers[j];
+			observer->DCOHandleGlobalChangeEventL(change);
+			}
+		}
+
+	// Reduce memory usage
+	iGlobalChanges.Reset();
+	iGlobalChanges.GranularCompress();
+	//
+	LOGTEXT("CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL() - end");
+	}
+
+TBool CLogServDatabaseChangeTracker::IdleNotifyGlobalChangeEvents(TAny* aSelf)
+	{
+	CLogServDatabaseChangeTracker* self = reinterpret_cast<CLogServDatabaseChangeTracker*>(aSelf);
+	TRAPD(err, self->NotifyGlobalChangeEventsL());
+    UNUSED_VAR(err);
+	return EFalse;
+	}