sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "LogServDatabaseChangeTracker.h" sl@0: #include "LogChangeDefinition.h" sl@0: #include "LogServDatabaseTransactionInterface.h" sl@0: #include "logservpanic.h" sl@0: #include "LogServBackupInterface.h" sl@0: sl@0: // Constants sl@0: const TInt KLogArrayGranularityObservers = 3; sl@0: const TInt KLogArrayGranularityGlobalChanges = 2; sl@0: sl@0: #define UNUSED_VAR(a) a = a sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: // -----> CLogServDatabaseChangeTracker (source) sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: CLogServDatabaseChangeTracker::CLogServDatabaseChangeTracker(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, TInt aPriority) sl@0: : CActive(aPriority), iDatabase(aDatabase), iBackupInterface(aBackupInterface), iObservers(KLogArrayGranularityObservers), iGlobalChanges(KLogArrayGranularityGlobalChanges) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CLogServDatabaseChangeTracker::~CLogServDatabaseChangeTracker() sl@0: { sl@0: Cancel(); sl@0: // sl@0: iBackupInterface.BIObserverRemove(*this); sl@0: iNotifier.Close(); sl@0: iObservers.Close(); sl@0: iGlobalChanges.Close(); sl@0: // sl@0: delete iIdler; sl@0: delete iChanges; sl@0: } sl@0: sl@0: void CLogServDatabaseChangeTracker::ConstructL() sl@0: { sl@0: iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectChangeTracker); sl@0: iChanges = CLogChangeDefinition::NewL(); sl@0: // sl@0: const TInt error = iNotifier.Open(iDatabase.DTIDatabase()); sl@0: User::LeaveIfError(error); sl@0: // sl@0: Request(); sl@0: // sl@0: iIdler = CIdle::NewL(CActive::EPriorityIdle); sl@0: } sl@0: sl@0: CLogServDatabaseChangeTracker* CLogServDatabaseChangeTracker::NewL(MLogServDatabaseTransactionInterface& aDatabase, MLogServBackupInterface& aBackupInterface, TInt aPriority) sl@0: { sl@0: CLogServDatabaseChangeTracker* self = new(ELeave) CLogServDatabaseChangeTracker(aDatabase, aBackupInterface, aPriority); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CLogServDatabaseChangeTracker::DCISubmitChangedEventContextL(TLogDatabaseChangeType aType, TLogId aEventId) sl@0: { sl@0: __ASSERT_DEBUG(aType != ELogChangeTypeUndefined, Panic(ELogUnrecognizedChangeType2)); sl@0: iChanges->AddL(aEventId, aType, KErrGeneral); sl@0: } sl@0: sl@0: void CLogServDatabaseChangeTracker::DCISubmitGlobalChangeContextL(TUid aChangeType, TInt aContextParam1, TInt aContextParam2, TInt aContextParam3) sl@0: { sl@0: const TLogServDatabaseChangeDefinition item(aChangeType, aContextParam1, aContextParam2, aContextParam3); sl@0: User::LeaveIfError(iGlobalChanges.Append(item)); sl@0: // sl@0: iIdler->Cancel(); sl@0: iIdler->Start(TCallBack(IdleNotifyGlobalChangeEvents, this)); sl@0: } sl@0: sl@0: void CLogServDatabaseChangeTracker::DCIRequestChangeNotificationsL(MLogServDatabaseChangeObserver& aObserver) sl@0: { sl@0: const TInt error = iObservers.InsertInAddressOrder(&aObserver); sl@0: User::LeaveIfError(error); sl@0: } sl@0: sl@0: void CLogServDatabaseChangeTracker::DCIRequestChangeNotificationsCancel(MLogServDatabaseChangeObserver& aObserver) sl@0: { sl@0: const TInt error = iObservers.FindInAddressOrder(&aObserver); sl@0: if (error >= KErrNone) sl@0: iObservers.Remove(error); sl@0: } sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CLogServDatabaseChangeTracker::BOHandleEventL(TLogServBackupEvent aEvent) sl@0: { sl@0: switch(aEvent) sl@0: { sl@0: case EBackupStarting: sl@0: { sl@0: Cancel(); sl@0: iNotifier.Close(); sl@0: break; sl@0: } sl@0: case EBackupEnded: sl@0: { sl@0: const TInt error = iNotifier.Open(iDatabase.DTIDatabase()); sl@0: User::LeaveIfError(error); sl@0: Request(); sl@0: break; sl@0: } sl@0: default: sl@0: __ASSERT_DEBUG(EFalse, User::Invariant()); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CLogServDatabaseChangeTracker::RunL() sl@0: { sl@0: // We are only interested if a commit has occurred sl@0: const TInt completionCode = iStatus.Int(); sl@0: if (completionCode == RDbNotifier::ECommit) sl@0: { sl@0: LOGTEXT("CLogServDatabaseChangeTracker::RunL() - database commit"); sl@0: sl@0: // Notify all observers sl@0: NotifyObserversL(); sl@0: sl@0: // Reset changes sl@0: iChanges->Reset(); sl@0: } sl@0: Request(); sl@0: } sl@0: sl@0: void CLogServDatabaseChangeTracker::DoCancel() sl@0: { sl@0: iNotifier.Cancel(); sl@0: } sl@0: sl@0: TInt CLogServDatabaseChangeTracker::RunError(TInt /*aError*/) sl@0: { sl@0: // Ignore errors such as leaves from notifying observers sl@0: Request(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CLogServDatabaseChangeTracker::Request() sl@0: { sl@0: iNotifier.NotifyChange(iStatus); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CLogServDatabaseChangeTracker::NotifyObserversL() sl@0: { sl@0: LOGTEXT("CLogServDatabaseChangeTracker::NotifyObserversL()"); sl@0: // sl@0: const TInt count = iObservers.Count(); sl@0: for(TInt i=0; iDCOHandleChangeEventsL(*iChanges); sl@0: } sl@0: sl@0: // Reduce memory usage sl@0: iChanges->Reset(); sl@0: // sl@0: LOGTEXT("CLogServDatabaseChangeTracker::NotifyObserversL() - end"); sl@0: } sl@0: sl@0: void CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL() sl@0: { sl@0: LOGTEXT("CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL()"); sl@0: // sl@0: const TInt count = iGlobalChanges.Count(); sl@0: for(TInt i=0; iDCOHandleGlobalChangeEventL(change); sl@0: } sl@0: } sl@0: sl@0: // Reduce memory usage sl@0: iGlobalChanges.Reset(); sl@0: iGlobalChanges.GranularCompress(); sl@0: // sl@0: LOGTEXT("CLogServDatabaseChangeTracker::NotifyGlobalChangeEventsL() - end"); sl@0: } sl@0: sl@0: TBool CLogServDatabaseChangeTracker::IdleNotifyGlobalChangeEvents(TAny* aSelf) sl@0: { sl@0: CLogServDatabaseChangeTracker* self = reinterpret_cast(aSelf); sl@0: TRAPD(err, self->NotifyGlobalChangeEventsL()); sl@0: UNUSED_VAR(err); sl@0: return EFalse; sl@0: }