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 "LogNotify.h" sl@0: #include "logservpanic.h" sl@0: #include "LogServBackupInterface.h" sl@0: #include "LogServDatabaseChangeInterface.h" sl@0: sl@0: sl@0: CLogNotify::CLogNotify(MLogServBackupInterface& aBackupInterface, MLogServDatabaseChangeInterface& aChangeInterface, TInt aPriority) sl@0: : CTimer(aPriority), iBackupInterface(aBackupInterface), iChangeInterface(aChangeInterface), iCompleteClientMessage(ETrue) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CLogNotify::~CLogNotify() sl@0: { sl@0: LOGTEXT("CLogNotify::~CLogNotify()"); sl@0: sl@0: // This will only complete the client-side request if its not already sl@0: // been completed sl@0: Cancel(); sl@0: // sl@0: iChangeInterface.DCIRequestChangeNotificationsCancel(*this); sl@0: iBackupInterface.BIObserverRemove(*this); sl@0: sl@0: LOGTEXT("CLogNotify::~CLogNotify() - end"); sl@0: } sl@0: sl@0: void CLogNotify::ConstructL() sl@0: { sl@0: LOGTEXT("CLogNotify::ConstructL()"); sl@0: sl@0: CTimer::ConstructL(); sl@0: sl@0: // Register for change events sl@0: iChangeInterface.DCIRequestChangeNotificationsL(*this); sl@0: sl@0: // Register for backup events sl@0: iBackupInterface.BIObserverAddL(*this, MLogServBackupInterface::EObjectClientChangeNotifications); sl@0: sl@0: LOGTEXT("CLogNotify::ConstructL() - end"); sl@0: } sl@0: sl@0: CLogNotify* CLogNotify::NewL(MLogServBackupInterface& aBackupInterface, MLogServDatabaseChangeInterface& aChangeInterface, TInt aPriority) sl@0: { sl@0: CLogNotify* self = new(ELeave)CLogNotify(aBackupInterface, aChangeInterface, 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 CLogNotify::DCOHandleChangeEventsL(const CLogChangeDefinition& /*aChanges*/) sl@0: // sl@0: // Handle changes within the log database sl@0: // sl@0: { sl@0: LOGTEXT2("CLogNotify::DCOHandleChangeEventsL() - client thread is: %S", &iClientThreadName); sl@0: sl@0: // Increment number of changes but only notify the client side request sl@0: // if the delay timer isn't running. sl@0: ++iCommit; sl@0: // sl@0: if (!IsActive()) sl@0: CheckForChanges(); sl@0: sl@0: LOGTEXT("CLogNotify::DCOHandleChangeEventsL() - end"); sl@0: } sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CLogNotify::BOHandleEventL(TLogServBackupEvent aEvent) sl@0: { sl@0: switch(aEvent) sl@0: { sl@0: case EBackupStarting: sl@0: LOGTEXT("CLogNotify::BOHandleEventL(EBackupStarting)"); sl@0: sl@0: // A rather inelegant fix but gets rid of one whole class sl@0: iCompleteClientMessage = EFalse; sl@0: Cancel(); sl@0: iCompleteClientMessage = ETrue; sl@0: break; sl@0: sl@0: case EBackupEnded: sl@0: LOGTEXT("CLogNotify::BOHandleEventL(EBackupEnded)"); sl@0: // Simulate a change sl@0: ++iCommit; sl@0: if (!IsActive()) sl@0: CheckForChanges(); sl@0: break; sl@0: } sl@0: sl@0: LOGTEXT("CLogNotify::BOHandleEventL() - end"); sl@0: } sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CLogNotify::Notify(TTimeIntervalMicroSeconds32 aDelay, const RMessage2& aMessage) sl@0: sl@0: { sl@0: #ifdef LOGGING_ENABLED sl@0: RThread t; sl@0: aMessage.Client(t); sl@0: iClientThreadName = t.Name(); sl@0: t.Close(); sl@0: LOGTEXT3("CLogNotify::Notify(%d, %S)", aDelay.Int(), &iClientThreadName); sl@0: #endif sl@0: sl@0: __ASSERT_DEBUG(!IsActive(), Panic(ELogAlreadyActive18)); sl@0: Cancel(); sl@0: sl@0: // Reset our change counter sl@0: if (iLastCommit == 0) sl@0: iLastCommit = iCommit; sl@0: sl@0: // Save a message pointer to client request status sl@0: iMessagePtr = aMessage; sl@0: sl@0: // Wait until the delay has passed before notifying clients of changes sl@0: After(aDelay); sl@0: sl@0: LOGTEXT("CLogNotify::Notify() - end"); sl@0: } sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CLogNotify::Cancel() sl@0: { sl@0: LOGTEXT2("CLogNotify::Cancel() - client thread is: %S", &iClientThreadName); sl@0: sl@0: CActive::Cancel(); sl@0: sl@0: // Reset sl@0: iLastCommit = 0; sl@0: sl@0: // Complete the client-side observer sl@0: if (iCompleteClientMessage) sl@0: CompleteClientRequest(KErrCancel); sl@0: sl@0: LOGTEXT("CLogNotify::Cancel() - end"); sl@0: } sl@0: sl@0: void CLogNotify::RunL() sl@0: // sl@0: // RunL is called if the timer has expired sl@0: // sl@0: { sl@0: LOGTEXT3("CLogNotify::RunL(%d) - client thread is: %S", iStatus.Int(), &iClientThreadName); sl@0: sl@0: CheckForChanges(); sl@0: sl@0: LOGTEXT("CLogNotify::RunL() - end"); sl@0: } sl@0: sl@0: void CLogNotify::DoCancel() sl@0: { sl@0: LOGTEXT2("CLogNotify::DoCancel() - client thread is: %S", &iClientThreadName); sl@0: sl@0: // This is what really cancel's us sl@0: CTimer::DoCancel(); sl@0: sl@0: LOGTEXT("CLogNotify::DoCancel() - end"); sl@0: } sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: void CLogNotify::CheckForChanges() sl@0: { sl@0: LOGTEXT4("CLogNotify::CheckForChanges() - iLastCommit = %d, iCommit = %d, client thread name: %S", iLastCommit, iCommit, &iClientThreadName); sl@0: sl@0: if (iLastCommit != iCommit) sl@0: { sl@0: LOGTEXT("CLogNotify::CheckForChanges() - changes detected, attempting to notify client"); sl@0: iLastCommit = iCommit; sl@0: CompleteClientRequest(RDbNotifier::ECommit); sl@0: } sl@0: sl@0: LOGTEXT("CLogNotify::CheckForChanges() - end"); sl@0: } sl@0: sl@0: void CLogNotify::CompleteClientRequest(TInt aCompletionCode) sl@0: { sl@0: LOGTEXT3("CLogNotify::CompleteClientRequest() - aCompletionCode = %d, thread: %S", aCompletionCode, &iClientThreadName); sl@0: sl@0: if (!iMessagePtr.IsNull()) sl@0: { sl@0: LOGTEXT2("CLogNotify::CompleteClientRequest() - completing outstanding client request status for thread: %S", &iClientThreadName); sl@0: iMessagePtr.Complete(aCompletionCode); sl@0: } sl@0: else sl@0: { sl@0: LOGTEXT2("CLogNotify::CompleteClientRequest() - thread %S doesn't have an outstanding notification request", &iClientThreadName); sl@0: } sl@0: sl@0: LOGTEXT("CLogNotify::CompleteClientRequest() - end"); sl@0: }