memspy/Engine/Source/Helpers/MemSpyEngineHelperProcess.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 16:45:49 +0300
branchRCL_3
changeset 43 ca8a1b6995f6
parent 0 a03f92240627
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 <memspy/engine/memspyenginehelperprocess.h>

// System includes
#include <e32debug.h>

// Driver includes
#include <memspy/driver/memspydriverclient.h>

// User includes
#include <memspy/engine/memspyengine.h>
#include <memspy/engine/memspyenginemidwife.h>
#include <memspy/engine/memspyengineoutputsink.h>
#include <memspy/engine/memspyengineobjectthread.h>
#include <memspy/engine/memspyengineobjectprocess.h>
#include <memspy/engine/memspyenginehelperchunk.h>
#include <memspy/engine/memspyenginehelpercodesegment.h>
#include <memspy/engine/memspyenginehelperthread.h>
#include <memspy/engine/memspyengineprocessmemorytracker.h>



CMemSpyEngineHelperProcess::CMemSpyEngineHelperProcess( CMemSpyEngine& aEngine )
:   iEngine( aEngine )
    {
    }

    
CMemSpyEngineHelperProcess::~CMemSpyEngineHelperProcess()
    {
    delete iUndertaker;
    iEngine.Midwife().RemoveObserver( *this );
    //
    iMemoryTrackers.ResetAndDestroy();
    iMemoryTrackers.Close();
    iMemoryTrackerAutoStartProcessList.Close();
    }


void CMemSpyEngineHelperProcess::ConstructL()
    {
    iUndertaker = CMemSpyEngineUndertaker::NewL( iEngine.Driver() );
    iUndertaker->AddObserverL( *this );
    iEngine.Midwife().AddObserverL( *this );
    }


CMemSpyEngineHelperProcess* CMemSpyEngineHelperProcess::NewL( CMemSpyEngine& aEngine )
    {
    CMemSpyEngineHelperProcess* self = new(ELeave) CMemSpyEngineHelperProcess( aEngine );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }


EXPORT_C void CMemSpyEngineHelperProcess::ImpersonateL( TUint32 aSID )
    {
    const TInt err = iEngine.Driver().Impersonate( aSID );
    User::LeaveIfError( err );
    }


EXPORT_C void CMemSpyEngineHelperProcess::OutputProcessInfoL( const CMemSpyProcess& aProcess )
    {
    OutputProcessInfoL( aProcess, EFalse );
    }


EXPORT_C void CMemSpyEngineHelperProcess::OutputProcessInfoDetailedL( const CMemSpyProcess& aProcess )
    {
    OutputProcessInfoL( aProcess, ETrue );
    }


void CMemSpyEngineHelperProcess::OutputProcessInfoL( const CMemSpyProcess& aProcess, TBool aDetailed )
    {
    const TUint pid = aProcess.Id();
    const TUint sid = aProcess.SID();
    RProcess process;
    User::LeaveIfError( iEngine.Driver().OpenProcess( pid, process ) );
    CleanupClosePushL( process );

    const TPtrC procName( aProcess.Name() );
    TBuf<512> infoBuf;
    //
    _LIT(KProcessInfo, "SUMMARY FOR PROCESS \'%S\'");
    infoBuf.Format(KProcessInfo, &procName);
    iEngine.Sink().OutputSectionHeadingL( infoBuf, '=' );
   
    _LIT(KProcessId, "Id");
    iEngine.Sink().OutputItemAndValueL( KProcessId, pid );

    _LIT(KProcessPri, "Priority");
    TBuf<30> priority;
    const TProcessPriority procPriValue = process.Priority();
    CMemSpyProcess::AppendPriority( priority, procPriValue );
    iEngine.Sink().OutputItemAndValueL( KProcessPri, priority );

    _LIT(KProcessSID, "SID");
    iEngine.Sink().OutputItemAndValueL( KProcessSID, sid, ETrue );
    CleanupStack::PopAndDestroy( &process );

    if  ( aDetailed )
        {
        iEngine.ProcessSuspendLC( pid );
        iEngine.HelperChunk().OutputChunkInfoForProcessL( aProcess );
        iEngine.HelperCodeSegment().OutputCodeSegmentsL( pid, infoBuf, KNullDesC, '-', ETrue );
        CleanupStack::PopAndDestroy(); // ProcessSuspendLC
        }

    const TInt count = aProcess.Count();
    for(TInt i=0; i<count; i++)
        {
        const CMemSpyThread& thread = aProcess.At( i );
        iEngine.HelperThread().OutputThreadInfoL( thread, aDetailed );
        }
    }


EXPORT_C void CMemSpyEngineHelperProcess::SetMemoryTrackingAutoStartProcessListL( const RArray<TUid>& aProcessUids )
    {
    iEngine.Driver().ProcessInspectionAutoStartItemsReset();
    //
    const TInt count = aProcessUids.Count();
    iMemoryTrackerAutoStartProcessList.Reset();
    //
    for( TInt i=0; i<count; i++ )
        {
        const TUid uid = aProcessUids[ i ];
#ifdef _DEBUG
        RDebug::Printf( "CMemSpyEngineHelperProcess::SetMemoryTrackingAutoStartProcessListL() - uid[%2d] => 0x%08x", i, uid.iUid );
#endif
        //
        User::LeaveIfError( iMemoryTrackerAutoStartProcessList.Append( uid ) );
        //
        const TInt driverErr = iEngine.Driver().ProcessInspectionAutoStartItemsAdd( uid.iUid );
#ifdef _DEBUG
        RDebug::Printf( "CMemSpyEngineHelperProcess::SetMemoryTrackingAutoStartProcessListL() - driver err: %d", driverErr );
#endif
        User::LeaveIfError( driverErr );
        }
    }


CMemSpyEngineProcessMemoryTracker* CMemSpyEngineHelperProcess::TrackerOrNull( const TProcessId& aId )
    {
    CMemSpyEngineProcessMemoryTracker* ret = NULL;
    //
    const TInt count = iMemoryTrackers.Count();
    for( TInt i=0; i<count; i++ )
        {
        CMemSpyEngineProcessMemoryTracker* tracker = iMemoryTrackers[ i ];
        //
        if ( tracker->ProcessId() == aId )
            {
            ret = tracker;
            break;
            }
        }
    //
    return ret;
    }
    

CMemSpyEngineProcessMemoryTracker& CMemSpyEngineHelperProcess::TrackerL( const TProcessId& aId )
    {
    CMemSpyEngineProcessMemoryTracker* tracker = TrackerOrNull( aId );
    //
    if  ( tracker == NULL )
        {
        // Make a new entry
        tracker = CMemSpyEngineProcessMemoryTracker::NewLC( iEngine, aId );
        User::LeaveIfError( iMemoryTrackers.Append( tracker ) );
        CleanupStack::Pop( tracker );
        }
    //
    return *tracker;
    }


CMemSpyEngineProcessMemoryTracker& CMemSpyEngineHelperProcess::TrackerL( const CMemSpyProcess& aProcess )
    {
    return TrackerL( aProcess.Id() );
    }


void CMemSpyEngineHelperProcess::ThreadIsBornL( const TThreadId& aId, const RThread& aThread )
    {
#ifdef _DEBUG
    RDebug::Printf( "CMemSpyEngineHelperProcess::ThreadIsBornL() - aId: 0x%08x, aThread handle: 0x%08x", (TUint) aId, aThread.Handle() );
#else
    (void) aId;
    (void) aThread;
#endif
    }


void CMemSpyEngineHelperProcess::ProcessIsBornL( const TProcessId& aId, const RProcess& aProcess )
    {
#ifdef _DEBUG
    RDebug::Printf( "CMemSpyEngineHelperProcess::ProcessIsBornL() - aId: 0x%08x, aProcess handle: 0x%08x", (TUint) aId, aProcess.Handle() );
#else
    (void) aId;
    (void) aProcess;
#endif

    if ( aProcess.Handle() != KNullHandle )
        {
        const TBool isAutoStart = IsAutoStartupProcess( aProcess.SecureId() );
        //
        if ( isAutoStart )
            {
            CMemSpyEngineProcessMemoryTracker& tracker = TrackerL( aId );
            tracker.StartL();
            }
        }
    }


void CMemSpyEngineHelperProcess::ThreadIsDeadL( const TThreadId& aId, const RThread& aThread )
    {
#ifdef _DEBUG
    RDebug::Printf( "CMemSpyEngineHelperProcess::ThreadIsDeadL() - aId: 0x%08x, aThread handle: 0x%08x", (TUint) aId, aThread.Handle() );
#else
    (void) aId;
    (void) aThread;
#endif
    }


void CMemSpyEngineHelperProcess::ProcessIsDeadL( const TProcessId& aId, const RProcess& aProcess )
    {
#ifdef _DEBUG
    RDebug::Printf( "CMemSpyEngineHelperProcess::ProcessIsDeadL() - aId: 0x%08x, aProcess handle: 0x%08x", (TUint) aId, aProcess.Handle() );
#else
    (void) aProcess;
#endif

    CMemSpyEngineProcessMemoryTracker* tracker = TrackerOrNull( aId );
    if  ( tracker )
        {
#ifdef _DEBUG
        RDebug::Printf( "CMemSpyEngineHelperProcess::ProcessIsDeadL() - tracker for this process should take care of cleanup by itself..." );
#endif
        }
    }
    

TBool CMemSpyEngineHelperProcess::IsAutoStartupProcess( TUid aUid ) const
    {
    TBool match = EFalse;
    //
    const TInt count = iMemoryTrackerAutoStartProcessList.Count();
    for( TInt i=0; i<count; i++ )
        {
        const TUid uid = iMemoryTrackerAutoStartProcessList[ i ];
        if ( uid == aUid )
            {
            match = ETrue;
            break;
            }
        }
    //
#ifdef _DEBUG
    RDebug::Printf( "CMemSpyEngineHelperProcess::IsAutoStartupProcess() - aUid: 0x%08x, ret: %d", aUid.iUid, match );
#endif
    return match;
    }