devicediagnosticsfw/diagframework/src/diaglogeventeraser.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:27:42 +0100
branchRCL_3
changeset 26 19bba8228ff0
parent 0 b497e44ab2fc
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2007 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:  This is the implementation of the Diagnostics Log Event
*                Eraser, which is used to delete OS log entries.
*
*/


// System Include Files
#include <e32base.h>                        // CActiveSchedulerWait
#include <logcli.h>                         // CLogClient
#include <logview.h>                        // CLogViewEvent
#include <DiagFrameworkDebug.h>             // Debugging macros

// Local Include Files
#include "diaglogeventeraser.h"             // CDiagLogEventEraser
#include "diaglogeventeraserobserver.h"     // MDiagLogEventEraserObserver


// ============================ MEMBER FUNCTIONS =============================

// ---------------------------------------------------------------------------
// Static two-phase constructor.
// ---------------------------------------------------------------------------
//
EXPORT_C CDiagLogEventEraser* CDiagLogEventEraser::NewL(
    MDiagLogEventEraserObserver& aObserver,
    CLogFilter* aFilter )
    {
    LOGSTRING( "CDiagLogEventEraser::NewL()" )

    CleanupStack::PushL( aFilter );
    CDiagLogEventEraser* self = new ( ELeave ) CDiagLogEventEraser(
        aObserver,
        aFilter );
    CleanupStack::Pop( aFilter );

    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );

    return self;
    }

// ---------------------------------------------------------------------------
// Destructor.
// ---------------------------------------------------------------------------
//
EXPORT_C CDiagLogEventEraser::~CDiagLogEventEraser()
    {
    LOGSTRING( "CDiagLogEventEraser::~CDiagLogEventEraser()" )

    Cancel();

    delete iLogFilter;
    delete iLogView;
    delete iLogClient;
    delete iWaitScheduler;

    iFsSession.Close();
    }

// ---------------------------------------------------------------------------
// Gets the filter to use when erasing logs.
// ---------------------------------------------------------------------------
//
EXPORT_C CLogFilter& CDiagLogEventEraser::Filter()
    {
    LOGSTRING( "CDiagLogEventEraser::Filter()" )
    return *iLogFilter;
    }

// ---------------------------------------------------------------------------
// Gets the log client used for the log erasure.
// ---------------------------------------------------------------------------
//
EXPORT_C CLogClient& CDiagLogEventEraser::LogClient()
    {
    LOGSTRING( "CDiagLogEventEraser::LogClient()" )
    return *iLogClient;
    }

// ---------------------------------------------------------------------------
// Begins asynchronous erasure of logs.  The observer will be notified of
// completion via callback.
// ---------------------------------------------------------------------------
//
EXPORT_C void CDiagLogEventEraser::StartAsyncEraseLogsL()
    {
    LOGSTRING( "CDiagLogEventEraser::StartAsyncEraseLogsL()" )

    __ASSERT_DEBUG( iState == EStateInitial, User::Invariant() );

    // Apply the filter.
    if( iLogView->SetFilterL( *iLogFilter, iStatus ) )
        {
        iState = EStateApplyingFilter;
        iIsDeletingSynchronous = EFalse;
        SetActive();
        }

    // There are no logs, so set this object active so that the callback will
    // be asynchronous.
    else
        {
        iState = EStateComplete;
        TRequestStatus* status = &iStatus;
        User::RequestComplete( status, KErrNone );
        SetActive();
        }
    }

// ---------------------------------------------------------------------------
// Begins synchronous erasure of logs.
// ---------------------------------------------------------------------------
//
EXPORT_C void CDiagLogEventEraser::EraseLogsL()
    {
    LOGSTRING( "CDiagLogEventEraser::EraseLogsL()" )

    __ASSERT_DEBUG( iState == EStateInitial, User::Invariant() );

    iError = KErrNone;

    // Apply the filter.  iWaitScheduler->Start() will return after the wait
    // scheduler is stopped.
    if( iLogView->SetFilterL( *iLogFilter, iStatus ) )
        {
        iState = EStateApplyingFilter;
        iIsDeletingSynchronous = ETrue;
        SetActive();
        iWaitScheduler->Start();
        }

    // If there is an error, iError will be set when the active object is run.
    User::LeaveIfError( iError );
    }

// ---------------------------------------------------------------------------
// The default constructor.
// ---------------------------------------------------------------------------
//
CDiagLogEventEraser::CDiagLogEventEraser(
    MDiagLogEventEraserObserver& aObserver,
    CLogFilter* aFilter )
:   CActive( EPriorityStandard ),
    iObserver( aObserver ),
    iLogFilter( aFilter )
    {
    LOGSTRING( "CDiagLogEventEraser::CDiagLogEventEraser()" )
    CActiveScheduler::Add( this );
    }

// ---------------------------------------------------------------------------
// The second phase constructor.
// ---------------------------------------------------------------------------
//
void CDiagLogEventEraser::ConstructL()
    {
    LOGSTRING( "CDiagLogEventEraser::ConstructL()" )

    User::LeaveIfError( iFsSession.Connect() );
    iWaitScheduler = new( ELeave ) CActiveSchedulerWait;
    iLogClient = CLogClient::NewL( iFsSession );
    iLogView = CLogViewEvent::NewL( *iLogClient );
    if ( !iLogFilter )
        {
        iLogFilter = CLogFilter::NewL();
        }
    }

// ---------------------------------------------------------------------------
// Handles the completion of log erasing and performs different operations
// depending on whether the erasing was asynchronous or not.
// ---------------------------------------------------------------------------
//
void CDiagLogEventEraser::HandleCompletionL( TInt aError )
    {
    LOGSTRING2( "CDiagLogEventEraser::HandleCompletionL( %d )", aError )

    // Reset the state so that the object can be reused.
    iState = EStateInitial;

    // For synchronous erasure, set the error code and stop the wait
    // scheduler, so that it will return in EraseLogsL.
    if ( iIsDeletingSynchronous )
        {
        iError = aError;
        iWaitScheduler->AsyncStop();
        }

    // For asynchronous erasure, inform the observer that erasing has
    // completed.
    else
        {
        iObserver.CompleteEventEraseL( aError );
        }
    }

// ---------------------------------------------------------------------------
// Handles the completion of active requests.
// ---------------------------------------------------------------------------
//
void CDiagLogEventEraser::RunL()
    {
    LOGSTRING( "CDiagLogEventEraser::RunL()" )

    // Check that the request completed successfully.
    if( iStatus != KErrNone )
        {
        HandleCompletionL( iStatus.Int() );
        return;
        }

    LOGSTRING2( "CDiagLogEventEraser::RunL() - State %d", iState )
    switch( iState )
        {
        case EStateApplyingFilter:
            {
            // The log view filter has been successfully applied.  Issue
            // another request to start processing log events.  Events are
            // read from last to first.  The reason for this arrangement is
            // that we are deleting entries while reading them.
            if( iLogView->LastL( iStatus ) )
                {
                iState = EStateReadingEntries;
                SetActive();
                }

            // There are no events in the view.
            else
                {
                HandleCompletionL( KErrNone );
                }

            break;
            }

        case EStateReadingEntries:
            {
            const CLogEvent& event = iLogView->Event();

            // The log event has been fetched successfully.  Ask the observer
            // if this event should be erased.  If so, issue another request
            // to begin erasing the event.
            if( iObserver.IsEventToBeDeleted( event ) )
                {
                iState = EStateDeletingEntry;
                iLogClient->DeleteEvent( event.Id(), iStatus );
                SetActive();
                }

            // The log event should not be erased, so get the next event.
            else if( iLogView->PreviousL( iStatus ) )
                {
                SetActive();
                }

            // There are no events in the view.
            else
                {
                HandleCompletionL( KErrNone );
                }

            break;
            }

        case EStateDeletingEntry:
            {
            // The log event was successfully deleted.  Issue another request
            // to read the next entry.
            if( iLogView->PreviousL( iStatus ) )
                {
                iState = EStateReadingEntries;
                SetActive();
                }

            // There are no events in the view.
            else
                {
                HandleCompletionL( KErrNone );
                }

            break;
            }

        case EStateComplete:
            {
            HandleCompletionL( KErrNone );
            break;
            }

        default:
            // This state should never be reached.
            LOGSTRING( "CDiagLogEventEraser::RunL() - Invalid State." )
            User::Invariant();
            break;
        }
    }

// ---------------------------------------------------------------------------
// Handles the cancellation of active requests.
// ---------------------------------------------------------------------------
//
void CDiagLogEventEraser::DoCancel()
    {
    LOGSTRING( "CDiagLogEventEraser::DoCancel()" )

    iLogView->Cancel();
    iLogClient->Cancel();
    iState = EStateInitial;
    }

// End of file