logsui/EngineSrc/CLogsBaseReader.cpp
changeset 0 e686773b3f54
--- /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 );
+    }
+