diff -r 5b6f26637ad3 -r f4a778e096c2 logsui/EngineSrc/CLogsBaseReader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/logsui/EngineSrc/CLogsBaseReader.cpp Wed Sep 01 12:29:52 2010 +0100 @@ -0,0 +1,511 @@ +/* +* Copyright (c) 2002 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: +* Implements interface for Logs reader. Common functionality. +* +*/ + + +// INCLUDE FILES +#include +#include "CLogsBaseReader.h" +#include "MLogsObserver.h" +#include "CLogsEvent.h" +#include "MLogsEventArray.h" +#include "LogsEngConsts.h" +#include +#include "CLogsEventData.h" +#include "CLogsEngine.h" + + +// CONSTANTS +const TInt KDeleteCountInit = -1; + +// CONSTANTS FOR DEBUGGING +#ifdef _DEBUG +_LIT(KPanicMsg,"CLogsBaseReader"); +#endif + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::CLogsBaseReader +// ---------------------------------------------------------------------------- +// +CLogsBaseReader::CLogsBaseReader( + RFs& aFsSession, + MLogsEventArray& aEventArray, + TLogsEventStrings& aStrings, + TLogsModel aModelId, + MLogsObserver* aObserver, + CLogsEngine* aLogsEngineRef + ) : + CActive( EPriorityStandard ), + iFsSession( aFsSession ), + iEventArray( aEventArray ), + iStrings( aStrings ), + iObserver( aObserver ), + iLogsEngineRef( aLogsEngineRef ), + iPhase( EInitial ), + iModelId( aModelId ), + iIndex( 0 ), + iInterrupted( EFalse ), + iState( EStateUndefined ), + iDirty( ETrue ), + iActivated( EFalse ), + iDeleteChangeCount( KDeleteCountInit ), + iStaticEmerg( ETrue ) + { + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::~CLogsBaseReader +// ---------------------------------------------------------------------------- +// +CLogsBaseReader::~CLogsBaseReader() + { + Cancel(); + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::BaseConstructL +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::BaseConstructL() + { + iLogClientRef = iLogsEngineRef->CLogClientRef(); + + if ( FeatureManager::FeatureSupported( KFeatureIdProtocolCdma ) ) + { + iStaticEmerg = EFalse; + } + } + + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::IsInterrupted +// ---------------------------------------------------------------------------- +// +TBool CLogsBaseReader::IsInterrupted() const + { + return iInterrupted; + } + + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::Interrupt +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::Interrupt() + { + if( iPhase != EInitial && iPhase != EDone ) + { + iInterrupted = ETrue; + iState = EStateInterrupted; + } + else if( iPhase == EDone ) + { + iState = EStateInterrupted; + iPhase = EFilter; + } + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::State +// ---------------------------------------------------------------------------- +// +TLogsState CLogsBaseReader::State() const + { + return iState; + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::NextL +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::NextL() + { + if( ! iInterrupted ) + { + if( DoNextL() ) //Implemented in derived reader + { + iState = EStateActive; + SetActive(); + } + else + { + iState = EStateFinished; + ReadingFinishedL(); + if( iObserver ) + { + iObserver->StateChangedL( this ); + } + } + } + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::SetObserver +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::SetObserver( MLogsObserver* aObserver ) + { + iObserver = aObserver; + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::ContinueL +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::ContinueL() + { + iInterrupted = EFalse; + + if( ! IsActive() ) + { + NextL(); + } + } + + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::DoCancel +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::DoCancel() //From CActive + { + iPhase = EInitial; + iState = EStateUndefined; + iLogClientRef->Cancel(); + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::RunL +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::RunL() + { + + if( iStatus != KErrNone ) + { + iState = EStateError; + if( iObserver ) + { + iObserver->StateChangedL( this ); + } + } + else + { + switch( iPhase ) + { + case EFilter: + if( ViewCountL() == 0 ) + { + iEventArray.Reset(); + iPhase = EDone; + } + break; + + case ERead: + { + const CLogEvent& sourceEvent = Event(); + + //If operator notifies voicemail using proprietary CPHS-message there is no number. + //Sms stack is logging it using number="CPHS" so we need to skip those entries (NSIA-6SP9GC). + _LIT(kCphs, "CPHS"); + const TDesC& nbr = sourceEvent.Number(); + + if( nbr == kCphs ) + { + break; + } + + if( iEventArray.Count() <= iIndex ) //Append new entry to event array + { + // create new event + CLogsEvent* event = CLogsEvent::NewLC(); + // Event() reads current event from Logs database + ConstructEventL( *event, sourceEvent ); //dest, source + // Append to end of array, when reading array first time + iEventArray.AppendL( *event ); //Ownership transferred + CleanupStack::Pop( event ); + } + else //Rewrite new entry on top of an old entry in event array + { + //Event() reads current event from Logs database + ConstructEventL( ( iEventArray.At( iIndex ) ), sourceEvent ); //dest, source + } + + // read duplicate counts if missed list and we're in phase of reading of the counts too. + if( iModelId == ELogsMissedModel && + iReadMissedDuplicateCounts ) + { + iPhase = EDuplicate; + } + else + { + ++iIndex; + } + + if( iIndex >= ViewCountL() ) + { + iPhase = EDone; + } + break; + } + + case EDuplicate: + + iPhase = ERead; + + iEventArray.At( iIndex ).SetDuplicates( //Retrieve duplicate count just retrieved in + static_cast( DuplicateCountL() + 1 ) ); //in call of NextL() + ++iIndex; + + if( iIndex >= ViewCountL() ) + { + iPhase = EDone; + } + break; + + case EInitial: // flow-through + case EDone: + default: + break; + } //end switch + + if( iPhase == EDone ) + { + //All events read + if( iModelId == ELogsMissedModel && !iReadMissedDuplicateCounts ) + { + //Finish first phase of reading missed calls, + iReadMissedDuplicateCounts = ETrue; + iState = EStateSemiFinished; //in order avoid scrollbar flicker etc in UI when StateChangedL is called + + if( iObserver ) + { + iObserver->StateChangedL( this ); + } + //Then immediately continue rereading missed calls now including the missed counts too + StartL(); + } + else + { + //Reading finished + ReadingFinishedL(); + iState = EStateFinished; //Inform UI etc all reading is now done + + if( iObserver ) + { + iObserver->StateChangedL( this ); + } + } + } + else + { + //Continue to next event + if( iObserver ) + { + iObserver->StateChangedL( this ); + } + NextL(); + } + } //endif + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::RunError +// ---------------------------------------------------------------------------- +// +TInt CLogsBaseReader::RunError(TInt aError) + { + if( aError == KErrAccessDenied ) + { + return KErrNone; + } + else + { + return aError; + } + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::ReadingFinishedL +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::ReadingFinishedL() + { + CheckArrayLengthL(); + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::CheckArrayLengthL +// +// If there are old items in the end of iEventArray that are not part of what was just read from db, +// get rid of those. This is called when data is (re)read from db. +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::CheckArrayLengthL() + { + TInt count( ViewCountL() ); //Item count in Log db view + + for( TInt i = iEventArray.Count(); i > count; i-- ) + { + iEventArray.Delete( i - 1 ); + } + + iEventArray.Compress(); + } + + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::DuplicateCountL +// ---------------------------------------------------------------------------- +// +TInt CLogsBaseReader::DuplicateCountL() const + { + return 0; + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::HandleLogViewChangeEventAddedL +// +// Called by Log Database engine when it notifies us that it has added an event to database +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::HandleLogViewChangeEventAddedL( + TLogId /*aId*/, + TInt /*aViewIndex*/, + TInt /*aChangeIndex*/, + TInt aTotalChangeCount ) + { + //Comment: HandleLogViewChangeEventAddedL seems to be called only once (and aTotalChangeCount is 1) even if + //there are multiple entries added to database in a batch. This seems to happen at least in wins emulator in Symbian 80a_200432. + //If problems in this area or changed behaviour, we need to consider same kind of optimization to here as is in + //HandleLogViewChangeEventDeletedL + + iDeleteChangeCount = KDeleteCountInit; //-1 + HandleViewChangeL( aTotalChangeCount ); + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::HandleLogViewChangeEventChangedL +// +// Called by Log Database engine when it notifies us that it has changed an event in the database +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::HandleLogViewChangeEventChangedL( + TLogId /*aId*/, + TInt /*aViewIndex*/, + TInt /*aChangeIndex*/, + TInt aTotalChangeCount ) + { + iDeleteChangeCount = KDeleteCountInit; //-1 + HandleViewChangeL( aTotalChangeCount ); + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::HandleLogViewChangeEventDeletedL +// +// Called by Log Database engine when it notifies us that it has deleted an event in the database +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::HandleLogViewChangeEventDeletedL( + TLogId /*aId*/, + TInt /*aViewIndex*/, + TInt /*aChangeIndex*/, + TInt aTotalChangeCount ) + { + //In order to prevent to re-reading the database multiple times, we call HandleViewChangeL only once. This is + //because HandleLogViewChangeEventDeletedL is called as many times as is the number of entries are deleted e.g. when + //deleteting old entries from database happens. However, aTotalChangeCount contains total number of deletions in + //a batch, so we can optimize the call to HandleViewChangeL to happen only even if we're called multiple times. + + //Note that CLogsEngine::StateChangedL is called by Logs engine when recent list entry has been deleted from db (it starts + //rereading of view data from db) + + if( aTotalChangeCount == 1 || ( aTotalChangeCount != iDeleteChangeCount ) ) + { + iDeleteChangeCount = aTotalChangeCount; + HandleViewChangeL( aTotalChangeCount ); + } + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::HandleViewChangeL +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::HandleViewChangeL( TInt aTotalChangeCount ) + { + if( aTotalChangeCount > 0 ) + { + iDirty = ETrue; + } + + if( iActivated && iDirty ) + { + StartL(); + } + } + + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::ActivateL +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::ActivateL() //Overridden method in derived classes may leave, that's why + { // name of this function indicates that this may leave. + iActivated = ETrue; + iReadMissedDuplicateCounts = EFalse;//ETrue: Read missed calls including duplicate counts. + //EFalse: Read missed calls view twice, first without duplicate counts, + //then again including duplicate counts (EMSH-6JDFBV). + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::DeActivate +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::DeActivate( ) + { + iActivated = EFalse; + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::IsDirty +// ---------------------------------------------------------------------------- +// +TBool CLogsBaseReader::IsDirty() const + { + return iDirty; + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::SetDirty +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::SetDirty() + { + iDirty = ETrue; + } + +// ---------------------------------------------------------------------------- +// CLogsBaseReader::BaseConstructEventL +// ---------------------------------------------------------------------------- +// +void CLogsBaseReader::BaseConstructEventL( + MLogsEvent& aDest, + const CLogEvent& aSource ) + { + aDest.InitializeEventL( aSource, iStrings, iModelId ); + } +