os/persistentdata/loggingservices/eventlogger/LogServ/src/LogServDatabaseChangeTracker.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "LogServDatabaseChangeTracker.h"
    17 #include "LogChangeDefinition.h"
    18 #include "LogServDatabaseTransactionInterface.h"
    19 #include "logservpanic.h"
    20 #include "LogServBackupInterface.h"
    21 
    22 // Constants
    23 const TInt KLogArrayGranularityObservers = 3;
    24 const TInt KLogArrayGranularityGlobalChanges = 2;
    25 
    26 #define UNUSED_VAR(a) a = a
    27 
    28 /////////////////////////////////////////////////////////////////////////////////////////
    29 // -----> CLogServDatabaseChangeTracker (source)
    30 /////////////////////////////////////////////////////////////////////////////////////////
    31 
    32 CLogServDatabaseChangeTracker::CLogServDatabaseChangeTracker(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, TInt aPriority)
    33 :	CActive(aPriority), iDatabase(aDatabase), iBackupInterface(aBackupInterface), iObservers(KLogArrayGranularityObservers), iGlobalChanges(KLogArrayGranularityGlobalChanges)
    34 	{
    35 	CActiveScheduler::Add(this);
    36 	}
    37 
    38 CLogServDatabaseChangeTracker::~CLogServDatabaseChangeTracker()
    39 	{
    40 	Cancel();
    41 	//
    42 	iBackupInterface.BIObserverRemove(*this);
    43 	iNotifier.Close();
    44 	iObservers.Close();
    45 	iGlobalChanges.Close();
    46 	//
    47 	delete iIdler;
    48 	delete iChanges;
    49 	}
    50 
    51 void CLogServDatabaseChangeTracker::ConstructL()
    52 	{
    53 	iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectChangeTracker);
    54 	iChanges = CLogChangeDefinition::NewL();
    55 	//
    56 	const TInt error = iNotifier.Open(iDatabase.DTIDatabase());
    57 	User::LeaveIfError(error);
    58 	//
    59 	Request();
    60 	//
    61 	iIdler = CIdle::NewL(CActive::EPriorityIdle);
    62 	}
    63 
    64 CLogServDatabaseChangeTracker* CLogServDatabaseChangeTracker::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, TInt aPriority)
    65 	{
    66 	CLogServDatabaseChangeTracker* self = new(ELeave) CLogServDatabaseChangeTracker(aDatabase, aBackupInterface, aPriority);
    67 	CleanupStack::PushL(self);
    68 	self->ConstructL();
    69 	CleanupStack::Pop(self);
    70 	return self;
    71 	}
    72 
    73 /////////////////////////////////////////////////////////////////////////////////////////
    74 /////////////////////////////////////////////////////////////////////////////////////////
    75 /////////////////////////////////////////////////////////////////////////////////////////
    76 
    77 void CLogServDatabaseChangeTracker::DCISubmitChangedEventContextL(TLogDatabaseChangeType aType, TLogId aEventId)
    78 	{
    79 	__ASSERT_DEBUG(aType != ELogChangeTypeUndefined, Panic(ELogUnrecognizedChangeType2));
    80 	iChanges->AddL(aEventId, aType, KErrGeneral);
    81 	}
    82 
    83 void CLogServDatabaseChangeTracker::DCISubmitGlobalChangeContextL(TUid aChangeType, TInt aContextParam1, TInt aContextParam2, TInt aContextParam3)
    84 	{
    85 	const TLogServDatabaseChangeDefinition item(aChangeType, aContextParam1, aContextParam2, aContextParam3);
    86 	User::LeaveIfError(iGlobalChanges.Append(item));
    87 	//
    88 	iIdler->Cancel();
    89 	iIdler->Start(TCallBack(IdleNotifyGlobalChangeEvents, this));
    90 	}
    91 
    92 void CLogServDatabaseChangeTracker::DCIRequestChangeNotificationsL(MLogServDatabaseChangeObserver& aObserver)
    93 	{
    94 	const TInt error = iObservers.InsertInAddressOrder(&aObserver);
    95 	User::LeaveIfError(error);
    96 	}
    97 
    98 void CLogServDatabaseChangeTracker::DCIRequestChangeNotificationsCancel(MLogServDatabaseChangeObserver& aObserver)
    99 	{
   100 	const TInt error = iObservers.FindInAddressOrder(&aObserver);
   101 	if	(error >= KErrNone)
   102 		iObservers.Remove(error);
   103 	}
   104 
   105 /////////////////////////////////////////////////////////////////////////////////////////
   106 /////////////////////////////////////////////////////////////////////////////////////////
   107 /////////////////////////////////////////////////////////////////////////////////////////
   108 
   109 void CLogServDatabaseChangeTracker::BOHandleEventL(TLogServBackupEvent aEvent)
   110 	{
   111 	switch(aEvent)
   112 		{
   113 	case EBackupStarting:
   114 		{
   115 		Cancel();
   116 		iNotifier.Close();
   117 		break;
   118 		}
   119 	case EBackupEnded:
   120 		{
   121 		const TInt error = iNotifier.Open(iDatabase.DTIDatabase());
   122 		User::LeaveIfError(error);
   123 		Request();
   124 		break;
   125 		}
   126 	default:
   127 		__ASSERT_DEBUG(EFalse, User::Invariant());
   128 		break;
   129 		}
   130 	}
   131 
   132 /////////////////////////////////////////////////////////////////////////////////////////
   133 /////////////////////////////////////////////////////////////////////////////////////////
   134 /////////////////////////////////////////////////////////////////////////////////////////
   135 
   136 void CLogServDatabaseChangeTracker::RunL()
   137 	{
   138 	// We are only interested if a commit has occurred
   139 	const TInt completionCode = iStatus.Int();
   140 	if	(completionCode == RDbNotifier::ECommit)
   141 		{
   142 		LOGTEXT("CLogServDatabaseChangeTracker::RunL() - database commit");
   143 
   144 		// Notify all observers
   145 		NotifyObserversL();
   146 
   147 		// Reset changes
   148 		iChanges->Reset();
   149 		}
   150 	Request();
   151 	}
   152 
   153 void CLogServDatabaseChangeTracker::DoCancel()
   154 	{
   155 	iNotifier.Cancel();
   156 	}
   157 
   158 TInt CLogServDatabaseChangeTracker::RunError(TInt /*aError*/)
   159 	{
   160 	// Ignore errors such as leaves from notifying observers
   161 	Request();
   162 	return KErrNone;
   163 	}
   164 
   165 /////////////////////////////////////////////////////////////////////////////////////////
   166 /////////////////////////////////////////////////////////////////////////////////////////
   167 /////////////////////////////////////////////////////////////////////////////////////////
   168 
   169 void CLogServDatabaseChangeTracker::Request()
   170 	{
   171 	iNotifier.NotifyChange(iStatus);
   172 	SetActive();
   173 	}
   174 
   175 void CLogServDatabaseChangeTracker::NotifyObserversL()
   176 	{
   177 	LOGTEXT("CLogServDatabaseChangeTracker::NotifyObserversL()");
   178 	//
   179 	const TInt count = iObservers.Count();
   180 	for(TInt i=0; i<count; i++)
   181 		{
   182 		MLogServDatabaseChangeObserver* observer = iObservers[i];
   183 		observer->DCOHandleChangeEventsL(*iChanges);
   184 		}
   185 
   186 	// Reduce memory usage
   187 	iChanges->Reset();
   188 	//
   189 	LOGTEXT("CLogServDatabaseChangeTracker::NotifyObserversL() - end");
   190 	}
   191 
   192 void CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL()
   193 	{
   194 	LOGTEXT("CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL()");
   195 	//
   196 	const TInt count = iGlobalChanges.Count();
   197 	for(TInt i=0; i<count; i++)
   198 		{
   199 		const TLogServDatabaseChangeDefinition& change = iGlobalChanges[i];
   200 		//
   201 		const TInt observerCount = iObservers.Count();
   202 		for(TInt j=0; j<observerCount; j++)
   203 			{
   204 			MLogServDatabaseChangeObserver* observer = iObservers[j];
   205 			observer->DCOHandleGlobalChangeEventL(change);
   206 			}
   207 		}
   208 
   209 	// Reduce memory usage
   210 	iGlobalChanges.Reset();
   211 	iGlobalChanges.GranularCompress();
   212 	//
   213 	LOGTEXT("CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL() - end");
   214 	}
   215 
   216 TBool CLogServDatabaseChangeTracker::IdleNotifyGlobalChangeEvents(TAny* aSelf)
   217 	{
   218 	CLogServDatabaseChangeTracker* self = reinterpret_cast<CLogServDatabaseChangeTracker*>(aSelf);
   219 	TRAPD(err, self->NotifyGlobalChangeEventsL());
   220     UNUSED_VAR(err);
   221 	return EFalse;
   222 	}