--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/logsui/EngineSrc/CLogsBaseReader.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -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 <logcli.h>
+#include "CLogsBaseReader.h"
+#include "MLogsObserver.h"
+#include "CLogsEvent.h"
+#include "MLogsEventArray.h"
+#include "LogsEngConsts.h"
+#include <featmgr.h>
+#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<TInt8>( 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 );
+ }
+