memspyui/ui/avkon/src/MemSpyViewHeapTracking.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 15:15:20 +0300
branchRCL_3
changeset 21 b3cee849fa46
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 2009 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:
*
*/

#include "MemSpyViewHeapTracking.h"

// System includes
#include <hal.h>

// Engine includes
#include <memspy/engine/memspyengine.h>
#include <memspy/engine/memspyengineobjectprocess.h>
#include <memspy/engine/memspyengineobjectthread.h>
#include <memspy/engine/memspyengineobjectcontainer.h>
#include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
#include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
#include <memspy/engine/memspyenginehelpersysmemtracker.h>

// User includes
#include "MemSpyUiUtils.h"
#include "MemSpyViewMainMenu.h"
#include "MemSpyContainerObserver.h"
#include "MemSpyViewHeapTrackingSettings.h"
#include "MemSpyViewHeapTrackingResults.h"


CMemSpyViewHeapTracking::CMemSpyViewHeapTracking( CMemSpyEngine& aEngine, MMemSpyViewObserver& aObserver )
:   CMemSpyViewBase( aEngine, aObserver ),
    iState( EMemSpyViewHeapTrackingStateIdle )
    {
    if ( iEngine.HelperSysMemTracker().IsActive() )
        {
        iState = EMemSpyViewHeapTrackingStateTimerOn;
        }
    }


CMemSpyViewHeapTracking::~CMemSpyViewHeapTracking()
    {
    delete iStopTimerCallBack;
    iEngine.HelperSysMemTracker().RemoveObserver( this );
    }


void CMemSpyViewHeapTracking::ConstructL( const TRect& aRect, CCoeControl& aContainer, TAny* aSelectionRune )
    {
    _LIT( KTitle, "System-Wide Memory Tracking" );
    SetTitleL( KTitle );
    //
    CMemSpyViewBase::ConstructL( aRect, aContainer, aSelectionRune );
    
    // Backup current config because it may be overwritten with Basic/Full mode settings.
    CMemSpyEngineHelperSysMemTracker& swmt = iEngine.HelperSysMemTracker();
    TMemSpyEngineHelperSysMemTrackerConfig config;
    swmt.GetConfig( config );
    iOriginalConfig = config;
    
    if ( config.iMode != TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeCustom )
        {
        // Set config. Needed for updating config for Basic or Full mode.
        SetConfigByModeL( config.iMode, config );        
        }
        
    // Make sure the correct item is selected
    TInt index = 0;
    if  ( aSelectionRune != NULL )
        {
        const TMemSpyViewType viewType = (TMemSpyViewType) ((TInt) aSelectionRune);
        index = IndexByViewType( viewType );
        }
    iListBox->SetCurrentItemIndex( index );
    HandleListBoxItemSelectedL( index );
    }


void CMemSpyViewHeapTracking::RefreshL()
    {
    SetListBoxModelL();
    CMemSpyViewBase::RefreshL();
    }


TMemSpyViewType CMemSpyViewHeapTracking::ViewType() const
    {
    return EMemSpyViewTypeHeapTracking;
    }


CMemSpyViewBase* CMemSpyViewHeapTracking::PrepareParentViewL()
    {
    
    // Save custom settings even if mode is Basic or Full
    TRAP_IGNORE(
        CMemSpyEngineHelperSysMemTracker& swmt = iEngine.HelperSysMemTracker();
        TMemSpyEngineHelperSysMemTrackerConfig config;
        swmt.GetConfig( config );
        config.iEnabledCategories = iOriginalConfig.iEnabledCategories;
        config.iThreadNameFilter = iOriginalConfig.iThreadNameFilter;
        config.iDumpData = iOriginalConfig.iDumpData;
        swmt.SetConfigL( config );
        Settings().StoreSettingsL();
        );
    
    CMemSpyViewMainMenu* parent = new(ELeave) CMemSpyViewMainMenu( iEngine, iObserver );
    CleanupStack::PushL( parent );
    parent->ConstructL( Rect(), *Parent(), (TAny*) ViewType() );
    CleanupStack::Pop( parent );
    return parent;
    }


CMemSpyViewBase* CMemSpyViewHeapTracking::PrepareChildViewL()
    {
    CMemSpyViewBase* child = NULL;
    const TInt index = iListBox->CurrentItemIndex();
    
    // Get current config
    CMemSpyEngineHelperSysMemTracker& swmt = iEngine.HelperSysMemTracker();
    TMemSpyEngineHelperSysMemTrackerConfig config;
    swmt.GetConfig( config );
    
    //
    if  ( index == 0 )
        {
        // This is the start/stop toggle so we don't make a child view
        child = NULL; 

        // ... instead we either start or stop the tracker
        if  ( !iEngine.HelperSysMemTracker().IsActive() )
            {
            iState = EMemSpyViewHeapTrackingStateSingleOn;
            // Setting observer to be able to stop SWMT after first cycle is completed
            iEngine.HelperSysMemTracker().SetObserver( this );
            iEngine.HelperSysMemTracker().StartL();
            }

        // Redraw listbox 
        RefreshL();
        }
    else if  ( index == 1 )
        {
        // This is the start/stop toggle so we don't make a child view
        child = NULL; 

        // ... instead we either start or stop the tracker
        if  ( iEngine.HelperSysMemTracker().IsActive() && iState == EMemSpyViewHeapTrackingStateTimerOn )
            {
            iState = EMemSpyViewHeapTrackingStateIdle;
            iEngine.HelperSysMemTracker().StopL();
            }
        else if ( iState == EMemSpyViewHeapTrackingStateIdle )
            {
            iState = EMemSpyViewHeapTrackingStateTimerOn;
            iEngine.HelperSysMemTracker().StartL();
            }

        // Redraw listbox 
        RefreshL();
        }
    else if ( index == 2 )
        {
        switch ( config.iMode )
            {
            case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeBasic:
                {
                // Set Full mode
                SetConfigByModeL( TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeFull, config );
                break;
                }
            case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeFull:
                {
                // Set Custom mode
                SetConfigByModeL( TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeCustom, config );
                break;
                }
            case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeCustom:
                {
                // Set Basic mode
                SetConfigByModeL( TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeBasic, config );
                break;
                }
            default: break;
            }
                
        // Redraw listbox 
        RefreshL();
        }
    else if ( index == 3 )
        {        
        if ( config.iMode == TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeCustom )
            {
            child = new(ELeave) CMemSpyViewHeapTrackingSettings( iEngine, iObserver );
            }
        else
            {
            child = new(ELeave) CMemSpyViewHeapTrackingResults( iEngine, iObserver );
            }
        }
    else if ( index == 4 )
        {
        child = new(ELeave) CMemSpyViewHeapTrackingResults( iEngine, iObserver );
        }
    if  ( child )
        {
        CleanupStack::PushL( child );
        child->ConstructL( Rect(), *Parent() );
        CleanupStack::Pop( child );
        }
    
    //
    return child;
    }


void CMemSpyViewHeapTracking::SetListBoxModelL()
    {
    CDesCArrayFlat* model = new(ELeave) CDesCArrayFlat(5);
    CleanupStack::PushL( model );

    TBuf<KMaxFullName + 1> item;
    
    // Get current config
    CMemSpyEngineHelperSysMemTracker& swmt = iEngine.HelperSysMemTracker();
    TMemSpyEngineHelperSysMemTrackerConfig config;
    swmt.GetConfig( config );

    // 1st item
    _LIT( KItem1FormatEnable, "\tGet dump now" );
    model->AppendL( KItem1FormatEnable );

    
    // 1st item
    if  ( iEngine.HelperSysMemTracker().IsActive() && iState == EMemSpyViewHeapTrackingStateTimerOn )
        {
        _LIT( KItem1FormatEnable, "\tStop timer\t\t%d (sec)" );
        TName item;
        item.Format( KItem1FormatEnable, config.iTimerPeriod.Int() / 1000000 );
        model->AppendL( item );
        }
    else
        {
        _LIT( KItem1FormatEnable, "\tStart timer\t\t%d (sec)" );
        TName item;
        item.Format( KItem1FormatEnable, config.iTimerPeriod.Int() / 1000000 );
        model->AppendL( item );
        }
    
    // 2nd item
    switch ( config.iMode )
        {
        case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeBasic:
            {
            _LIT( KItem2Format, "\tTracking mode\t\tBasic" );
            model->AppendL( KItem2Format );        
            break;
            }
        case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeFull:
            {
            _LIT( KItem2Format, "\tTracking mode\t\tFull" );
            model->AppendL( KItem2Format );        
            break;
            }
        case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeCustom:
            {
            _LIT( KItem2Format, "\tTracking mode\t\tCustom" );
            model->AppendL( KItem2Format );
            
            // 3rd item
            TFullName item;
            if ( config.DumpData() && 
                config.iEnabledCategories & TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserHeap )
                {
                _LIT( KItem3Format, "\tSettings\t\t%d categ., dump" );
                item.Format( KItem3Format, config.EnabledCategoryCount() );
                }
            else
                {
                _LIT( KItem3Format, "\tSettings\t\t%d categories" );
                item.Format( KItem3Format, config.EnabledCategoryCount() );
                }
            model->AppendL( item );            
            break;
            }
        default: break;
        }
    
    // 4th item    
    const TInt cycleCount = iEngine.HelperSysMemTracker().MdcaCount();
    if ( cycleCount )
        {
        _LIT( KItem2Format, "\tResults\t\t%d cycles" );
        TFullName item;
        item.Format( KItem2Format, cycleCount );
        model->AppendL( item );
        }
    else
        {
        _LIT( KItem2Format, "\tResults\t\tNo results" );
        model->AppendL( KItem2Format );
        }

    // Set up list box
    CAknSettingStyleListBox* listbox = static_cast< CAknSettingStyleListBox* >( iListBox );
    listbox->Model()->SetItemTextArray( model );
    listbox->Model()->SetOwnershipType( ELbmOwnsItemArray );
    CleanupStack::Pop( model );
    }


void CMemSpyViewHeapTracking::HandleCyclesResetL()
    {
    }


void CMemSpyViewHeapTracking::HandleCycleStartedL( const CMemSpyEngineHelperSysMemTrackerCycle& /*aCycle*/ )
    {
    }


void CMemSpyViewHeapTracking::HandleCycleFinishedL( const CMemSpyEngineHelperSysMemTrackerCycle& /*aCycle*/ )
    {
    // Stopping SWMT does not work directly from this function.
    // It has to be made asynchronously.
    iStopTimerCallBack = new (ELeave) CAsyncCallBack( TCallBack( CMemSpyViewHeapTracking::AsyncStopTimerCallback, this ), CActive::EPriorityStandard );
    iStopTimerCallBack->CallBack();
    }


TInt CMemSpyViewHeapTracking::IndexByViewType( TMemSpyViewType aType )
    {
    // Get current config
    CMemSpyEngineHelperSysMemTracker& swmt = iEngine.HelperSysMemTracker();
    TMemSpyEngineHelperSysMemTrackerConfig config;
    swmt.GetConfig( config );
    
    TInt index = 0;
    //
    switch( aType )
        {
    default:
    case EMemSpyViewTypeHeapTrackingResults:
        {
        if ( config.iMode == TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeCustom )
            {
            index = 4;
            }
        else
            {
            index = 3;
            }
        break;
        }
    case EMemSpyViewTypeHeapTrackingSettings:
        index = 3;
        break;
        }
    //
    return index;
    }


void CMemSpyViewHeapTracking::SetConfigByModeL( TMemSpyEngineHelperSysMemTrackerConfig::TMemSpyEngineSysMemTrackerMode aMode, TMemSpyEngineHelperSysMemTrackerConfig& aConfig )
    {
    switch ( aMode )
        {
        case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeBasic:
            {
            aConfig.iMode = aMode;
            aConfig.iEnabledCategories = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserHeap |
                                         TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryUserStacks |
                                         TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryGlobalData |
                                         TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategorySystemMemory;
            aConfig.iDumpData = EFalse;
            break;
            }
        case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeFull:
            {
            aConfig.iMode = aMode;
            aConfig.iEnabledCategories = TMemSpyEngineHelperSysMemTrackerConfig::EMemSpyEngineSysMemTrackerCategoryAll;
            aConfig.iDumpData = ETrue;
            aConfig.iThreadNameFilter = KNullDesC;
            break;
            }
        case TMemSpyEngineHelperSysMemTrackerConfig::MemSpyEngineSysMemTrackerModeCustom:
            {
            aConfig.iMode = aMode;
            aConfig.iEnabledCategories = iOriginalConfig.iEnabledCategories;
            aConfig.iDumpData = iOriginalConfig.iDumpData;
            aConfig.iThreadNameFilter = iOriginalConfig.iThreadNameFilter;
            break;
            }
        default: User::Leave( KErrArgument );
        }
    // Push changes to SWMT
    CMemSpyEngineHelperSysMemTracker& swmt = iEngine.HelperSysMemTracker();
    swmt.SetConfigL( aConfig );
    Settings().StoreSettingsL();
    }


TInt CMemSpyViewHeapTracking::AsyncStopTimerCallback( TAny* aParam )
    {
    CMemSpyViewHeapTracking* view = static_cast<CMemSpyViewHeapTracking*>( aParam );
    return view->AsyncStopTimerCallback();
    }


TInt CMemSpyViewHeapTracking::AsyncStopTimerCallback()
    {
    iState = EMemSpyViewHeapTrackingStateIdle;
    iEngine.HelperSysMemTracker().RemoveObserver( this );
    TRAP_IGNORE(
        iEngine.HelperSysMemTracker().StopL();
        RefreshL();
        );
    delete iStopTimerCallBack;
    iStopTimerCallBack = NULL;
    return KErrNone;
    }