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 "LogViewObserver.h" sl@0: sl@0: // System includes sl@0: #include <s32mem.h> sl@0: sl@0: // User includes sl@0: #include <logwrap.h> sl@0: #include <logcli.h> sl@0: #include "logclipanic.h" sl@0: #include "logservcli.h" sl@0: #include "LogChangeDefinition.h" sl@0: #include "LogViewChangeObserverInternal.h" sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: // -----> CLogViewObserver (source) sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: CLogViewObserver::CLogViewObserver(CLogView& aView, CLogClient& aClient, MLogViewChangeObserverInternal& aObserver, TLogViewId aViewId, TInt aPriority) sl@0: : CActive(aPriority), iClient(aClient), iObserver(aObserver), iViewId(aViewId), iView(aView) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CLogViewObserver::~CLogViewObserver() sl@0: { sl@0: Cancel(); sl@0: // sl@0: delete iChanges; sl@0: } sl@0: sl@0: void CLogViewObserver::ConstructL() sl@0: { sl@0: iChanges = CLogChangeDefinition::NewL(); sl@0: RequestChanges(); sl@0: } sl@0: sl@0: CLogViewObserver* CLogViewObserver::NewL(CLogView& aView, CLogClient& aClient, MLogViewChangeObserverInternal& aObserver, TLogViewId aViewId, TInt aPriority) sl@0: { sl@0: CLogViewObserver* self = new(ELeave) CLogViewObserver(aView, aClient, aObserver, aViewId, 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: void CLogViewObserver::RequestChanges() sl@0: { sl@0: iClient.Session().Send(ELogViewChangeNotificationsRequest, TIpcArgs(iViewId), iStatus); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CLogViewObserver::RunL() sl@0: { sl@0: const TInt error = iStatus.Int(); sl@0: if (error == KErrServerTerminated) sl@0: { sl@0: // Effectively does a "delete this" sl@0: iView.NotifyLogServerTerminatedL(); sl@0: } sl@0: else if (error < KErrNone) sl@0: { sl@0: // Don't request any further changes. sl@0: } sl@0: else sl@0: { sl@0: const TInt changesSize = iStatus.Int(); sl@0: User::LeaveIfError(changesSize); sl@0: FetchChangesL(changesSize); sl@0: RequestChanges(); sl@0: NotifyObserverL(); sl@0: } sl@0: } sl@0: sl@0: TInt CLogViewObserver::RunError(TInt /*aError*/) sl@0: { sl@0: sl@0: // This point can be reached when RequestChanges has already been sl@0: // called, for example when an observer leaves when it is notified of sl@0: // a change. sl@0: // Check IsActive() before calling RequestChanges to avoid calling it sl@0: // twice in a row and causing a E32USER-CBase:42 panic. sl@0: sl@0: if (!IsActive()) sl@0: { sl@0: RequestChanges(); sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CLogViewObserver::DoCancel() sl@0: { sl@0: RequestChangesCancel(); sl@0: } sl@0: sl@0: void CLogViewObserver::RequestChangesCancel() sl@0: { sl@0: iClient.Session().Send(ELogViewChangeNotificationsCancel, TIpcArgs(iViewId)); sl@0: } sl@0: sl@0: void CLogViewObserver::FetchChangesL(TInt aBufferSizeRequired) sl@0: { sl@0: HBufC8* buffer = HBufC8::NewLC(aBufferSizeRequired); sl@0: TPtr8 pBuffer(buffer->Des()); sl@0: // sl@0: User::LeaveIfError(iClient.Session().Send(ELogViewFetchChanges, TIpcArgs(iViewId,aBufferSizeRequired,&pBuffer))); sl@0: // sl@0: iChanges->Reset(); sl@0: RDesReadStream stream(*buffer); sl@0: stream >> *iChanges; sl@0: CleanupStack::PopAndDestroy(buffer); sl@0: } sl@0: sl@0: void CLogViewObserver::NotifyObserverL() sl@0: { sl@0: TLogId id; sl@0: TInt viewIndex; sl@0: sl@0: // Copy the changes sl@0: const TInt count = iChanges->Count(); sl@0: if (!count) sl@0: return; sl@0: // sl@0: CLogChangeDefinition* changes = CLogChangeDefinition::NewL(*iChanges); sl@0: CleanupStack::PushL(changes); sl@0: iChanges->Reset(); sl@0: // sl@0: for(TInt i=0; i<count; i++) sl@0: { sl@0: const TLogDatabaseChangeType type = changes->At(i, id, viewIndex); sl@0: // sl@0: switch(type) sl@0: { sl@0: case ELogChangeTypeEventAdded: sl@0: iObserver.HandleLogViewChangeEventAddedL(id, viewIndex, i, count); sl@0: break; sl@0: case ELogChangeTypeEventChanged: sl@0: iObserver.HandleLogViewChangeEventChangedL(id, viewIndex, i, count); sl@0: break; sl@0: case ELogChangeTypeEventDeleted: sl@0: iObserver.HandleLogViewChangeEventDeletedL(id, viewIndex, i, count); sl@0: break; sl@0: case ELogChangeTypeLogCleared: sl@0: iObserver.HandleLogViewChangeEventLogClearedL(); sl@0: break; sl@0: default: sl@0: case ELogChangeTypeUndefined: sl@0: __ASSERT_DEBUG(EFalse, Panic(ELogUnexpectedChangeType)); sl@0: } sl@0: } sl@0: CleanupStack::PopAndDestroy(changes); sl@0: }