diff -r 000000000000 -r a03f92240627 memspy/Console/Source/ConsoleMenu.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memspy/Console/Source/ConsoleMenu.cpp Tue Feb 02 01:57:15 2010 +0200 @@ -0,0 +1,675 @@ +/* +* 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 "ConsoleMenu.h" + +// System includes +#include + +// Engine includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// User includes +#include "ConsoleConstants.h" +#include "ConsoleDWOperation.h" + + +CMemSpyConsoleMenu::CMemSpyConsoleMenu( CMemSpyEngine& aEngine, CConsoleBase& aConsole ) +: CActive( EPriorityHigh ), iEngine( aEngine ), iConsole( aConsole ) + { + CActiveScheduler::Add( this ); + iEngine.SetObserver( this ); + } + + +CMemSpyConsoleMenu::~CMemSpyConsoleMenu() + { + Cancel(); + iEngine.SetObserver( NULL ); + } + + +void CMemSpyConsoleMenu::ConstructL() + { + DrawMenuL(); + WaitForInput(); + } + + +CMemSpyConsoleMenu* CMemSpyConsoleMenu::NewLC( CMemSpyEngine& aEngine, CConsoleBase& aConsole ) + { + CMemSpyConsoleMenu* self = new(ELeave) CMemSpyConsoleMenu( aEngine, aConsole ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +void CMemSpyConsoleMenu::DrawMenuL() + { + iConsole.ClearScreen(); + + // First line - sink type (defaults to file) + _LIT( KLine1, "1 or T. Toggle output mode between file or trace [%S]" ); + if ( iEngine.SinkType() == ESinkTypeDebug ) + { + _LIT( KLine1Trace, "Trace" ); + iConsole.Printf( KLine1, &KLine1Trace ); + } + else + { + _LIT( KLine1File, "File" ); + iConsole.Printf( KLine1, &KLine1File ); + } + iConsole.Write( KMemSpyConsoleNewLine ); + + // Kernel heap dump + _LIT( KLine2, "2 or K. Dump kernel heap data" ); + iConsole.Write( KLine2 ); + iConsole.Write( KMemSpyConsoleNewLine ); + + // Kernel heap dump + _LIT( KLine3, "3 or O. Dump kernel object listing" ); + iConsole.Write( KLine3 ); + iConsole.Write( KMemSpyConsoleNewLine ); + + // Heap (CSV) listing + _LIT( KLine4, "4 or H. Heap CSV-information (for all threads)" ); + iConsole.Write( KLine4 ); + iConsole.Write( KMemSpyConsoleNewLine ); + + // Stack (CSV) listing + _LIT( KLine5, "5 or S. Stack CSV-information (for all threads)" ); + iConsole.Write( KLine5 ); + iConsole.Write( KMemSpyConsoleNewLine ); + + // Heap data + _LIT( KLine6, "6 or D. Get heap data for a user-thread" ); + iConsole.Write( KLine6 ); + iConsole.Write( KMemSpyConsoleNewLine ); + + // Heap cell listing + _LIT( KLine7, "7 or L. Get heap cell list for a user-thread" ); + iConsole.Write( KLine7 ); + iConsole.Write( KMemSpyConsoleNewLine ); + + // Exit key + _LIT( KLine8, "8 or X. Exit" ); + iConsole.Write( KLine8 ); + iConsole.Write( KMemSpyConsoleNewLine ); + + // Spacer + iConsole.Write( KMemSpyConsoleNewLine ); + iConsole.Write( KMemSpyConsoleNewLine ); + + // Status message + iStatusMessagePos = iConsole.CursorPos(); + RedrawStatusMessage(); + + // Spacer + iConsole.Write( KMemSpyConsoleNewLine ); + + // Show input prompt. + iCommandPromptPos = iConsole.CursorPos(); + RedrawInputPrompt(); + } + + +void CMemSpyConsoleMenu::WaitForInput() + { + ASSERT( !IsActive() ); + iConsole.Read( iStatus ); + SetActive(); + } + + +void CMemSpyConsoleMenu::RunL() + { + TKeyCode key = iConsole.KeyCode(); + // +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::RunL() - START - key = %d", key ); +#endif + // + if ( key == EKeyEnter || key == KMemSpyUiS60KeyCodeButtonOk || key == KMemSpyUiS60KeyCodeRockerEnter ) + { + TRAP_IGNORE( ProcessCommandBufferL() ); + } + else if ( key == EKeyEscape || key == KMemSpyUiS60KeyCodeButtonCancel ) + { + ClearCommandBuffer(); + RedrawInputPrompt(); + } + else if ( key == EKeyBackspace ) + { + const TInt cmdBufLength = iCommandBuffer.Length(); + if ( cmdBufLength > 0 ) + { + iCommandBuffer.SetLength( cmdBufLength - 1 ); + RedrawInputPrompt(); + } + } + else + { + TChar character( key ); + if ( character.IsPrint() ) + { + if ( iCommandBuffer.Length() < iCommandBuffer.MaxLength() ) + { + iCommandBuffer.Append( TChar( key ) ); + } + + RedrawInputPrompt(); + } + } + + WaitForInput(); + +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::RunL() - END" ); +#endif + } + + +void CMemSpyConsoleMenu::DoCancel() + { + iConsole.ReadCancel(); + } + + +void CMemSpyConsoleMenu::OnCmdSinkTypeToggleL() + { + if ( iEngine.SinkType() == ESinkTypeDebug ) + { + iEngine.InstallSinkL( ESinkTypeFile ); + } + else + { + iEngine.InstallSinkL( ESinkTypeDebug ); + } + } + + +void CMemSpyConsoleMenu::OnCmdHeapDataKernelL() + { +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdHeapDataKernelL() - START" ); +#endif + + _LIT( KMsg, "Ouputting Kernel data..." ); + RedrawStatusMessage( KMsg ); + + iEngine.HelperHeap().OutputHeapDataKernelL(); + + RedrawStatusMessage( KNullDesC ); + } + + +void CMemSpyConsoleMenu::OnCmdKernelObjectListingL() + { +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdKernelObjectListingL() - START" ); +#endif + + _LIT( KMsg, "Ouputting Kernel Object listing..." ); + RedrawStatusMessage( KMsg ); + // + CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers(); + CMemSpyEngineGenericKernelObjectContainer* model = kernelContainerManager.ObjectsAllL(); + CleanupStack::PushL( model ); + // + CMemSpyEngineOutputSink& sink = iEngine.Sink(); + model->OutputL( sink ); + // + CleanupStack::PopAndDestroy( model ); + + RedrawStatusMessage( KNullDesC ); + } + + +void CMemSpyConsoleMenu::OnCmdCSVListingStackL() + { +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdCSVListingStackL() - START" ); +#endif + + iEngine.HelperStack().OutputStackInfoForDeviceL(); + } + + +void CMemSpyConsoleMenu::OnCmdCSVListingHeapL() + { +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdCSVListingHeapL() - START" ); +#endif + + iEngine.HelperHeap().OutputHeapInfoForDeviceL(); + } + + +void CMemSpyConsoleMenu::OnCmdHeapDataUserL() + { +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdHeapDataUserL() - START" ); +#endif + + GetProcessName(); + + // Work out what to do. + iCommandBuffer.Trim(); + +#ifdef _DEBUG + RDebug::Print( _L("[MCon] CMemSpyConsoleMenu::OnCmdHeapDataUserL() - requested dump heap for proc: %S"), &iCommandBuffer ); +#endif + + if ( iCommandBuffer.Length() > 0 ) + { + iConsole.Write( KMemSpyConsoleNewLine ); + iConsole.Write( KMemSpyConsoleNewLine ); + // + HBufC* cmdBuf = HBufC::NewLC( KMemSpyMaxInputBufferLength + 10 ); + TPtr pCmdBuf( cmdBuf->Des() ); + pCmdBuf.Copy( iCommandBuffer ); + pCmdBuf.Append( KMemSpyConsoleWildcardCharacter ); + // + CMemSpyEngineObjectContainer& container = iEngine.Container(); + const TInt count = container.Count(); + TFullName fullThreadName; + // + TInt index = 0; +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::OnCmdHeapDataUserL() - procCount: %d", count ); +#endif + + while( index < count ) + { + CMemSpyProcess& process = container.At( index ); + const TPtrC processName( process.Name() ); +#ifdef _DEBUG + RDebug::Print( _L("[MCon] CMemSpyConsoleMenu::OnCmdHeapDataUserL() - procName: 0x%08x %S"), &process, &processName ); +#endif + + // + if ( processName.MatchF( pCmdBuf ) >= 0 ) + { + _LIT( KProcessingRequest, "** Dumping Heap Data for thread: %S" ); + const TInt threadCount = process.Count(); + for( TInt i=0; i 0 ) + { + iConsole.Write( KMemSpyConsoleNewLine ); + iConsole.Write( KMemSpyConsoleNewLine ); + // + HBufC* cmdBuf = HBufC::NewLC( KMemSpyMaxInputBufferLength + 10 ); + TPtr pCmdBuf( cmdBuf->Des() ); + pCmdBuf.Copy( iCommandBuffer ); + pCmdBuf.Append( KMemSpyConsoleWildcardCharacter ); + // + CMemSpyEngineObjectContainer& container = iEngine.Container(); + const TInt count = container.Count(); + TFullName fullThreadName; + // + TInt index = 0; + while( index < count ) + { + CMemSpyProcess& process = container.At( index ); + const TPtrC processName( process.Name() ); + // + if ( processName.MatchF( pCmdBuf ) >= 0 ) + { + _LIT( KProcessingRequest, "** Dumping Heap Cell List for thread: %S" ); + const TInt threadCount = process.Count(); + for( TInt i=0; i 0 ) + { + iCommandBuffer.SetLength( cmdBufLength - 1 ); + RedrawInputPrompt(); + } + } + else + { + TChar character( key ); + if ( character.IsPrint() ) + { + if ( iCommandBuffer.Length() < iCommandBuffer.MaxLength() ) + { + iCommandBuffer.Append( TChar( key ) ); + } + + RedrawInputPrompt(); + } + } + } + } + + +void CMemSpyConsoleMenu::HandleMemSpyEngineEventL( MMemSpyEngineObserver::TEvent aEvent, TAny* aContext ) + { + if ( aEvent == MMemSpyEngineObserver::EHandleClientServerOperationRequest ) + { + const TInt function = reinterpret_cast< TInt >( aContext ); + InitiateMemSpyClientServerOperationL( function ); + } + } + + +void CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL( TInt aOpCode ) + { +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - START - aOpCode: %d, iRunningDeviceWideOperation: %d", aOpCode, iRunningDeviceWideOperation ); +#endif + // + if ( aOpCode == EMemSpyClientServerOpExit ) + { + // Exit console app UI + CActiveScheduler::Stop(); + } + else + { + CMemSpyDeviceWideOperations::TOperation op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary; + switch( aOpCode ) + { + case EMemSpyClientServerOpSummaryInfo: + op = CMemSpyDeviceWideOperations::EPerEntityGeneralSummary; + break; + case EMemSpyClientServerOpSummaryInfoDetailed: + op = CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed; + break; + // + case EMemSpyClientServerOpHeapInfo: + op = CMemSpyDeviceWideOperations::EPerEntityHeapInfo; + break; + case EMemSpyClientServerOpHeapCellListing: + op = CMemSpyDeviceWideOperations::EPerEntityHeapCellListing; + break; + case EMemSpyClientServerOpHeapData: + op = CMemSpyDeviceWideOperations::EPerEntityHeapData; + break; + // + case EMemSpyClientServerOpStackInfo: + op = CMemSpyDeviceWideOperations::EPerEntityStackInfo; + break; + case EMemSpyClientServerOpStackDataUser: + op = CMemSpyDeviceWideOperations::EPerEntityStackDataUser; + break; + case EMemSpyClientServerOpStackDataKernel: + op = CMemSpyDeviceWideOperations::EPerEntityStackDataKernel; + break; + + // These are not supported by the console UI + default: + case EMemSpyClientServerOpBitmapsSave: + case EMemSpyClientServerOpSendToBackground: + case EMemSpyClientServerOpBringToForeground: + User::Leave( KErrNotSupported ); + break; + } + + if ( iRunningDeviceWideOperation ) + { + User::Leave( KErrInUse ); + } + else + { + iRunningDeviceWideOperation = ETrue; + TRAP_IGNORE( CMemSpyDeviceWideOperationWaiter::ExecuteLD( iEngine, op ) ); + iRunningDeviceWideOperation = EFalse; + } + } + +#ifdef _DEBUG + RDebug::Printf( "[MCon] CMemSpyConsoleMenu::InitiateMemSpyClientServerOperationL() - END - aOpCode: %d", aOpCode ); +#endif + } + + +