--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspyui/ui/avkon/src/MemSpyViewProcesses.cpp Tue Aug 31 15:15:20 2010 +0300
@@ -0,0 +1,687 @@
+/*
+* 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 "MemSpyViewProcesses.h"
+
+// System includes
+#include <aknsfld.h>
+#include <AknQueryDialog.h>
+#include <memspyui.rsg>
+
+// 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/memspyenginehelperprocess.h>
+#include <memspysession.h>
+#include <memspy/engine/memspyengineutils.h>
+
+// User includes
+#include "MemSpyViewThreads.h"
+#include "MemSpyViewMainMenu.h"
+#include "MemSpyContainerObserver.h"
+#include "MemSpyUiUtils.h"
+
+// Constants
+const TInt KMemSpyMaxSearchTextLength = 30;
+const TInt KMemSpyMaxSearchTextLengthWithWildcards = KMemSpyMaxSearchTextLength + 4;
+
+
+CMemSpyViewProcesses::CMemSpyViewProcesses( RMemSpySession& aSession, MMemSpyViewObserver& aObserver )
+: CMemSpyViewBase( aSession, aObserver )
+ {
+ }
+
+CMemSpyViewProcesses::CMemSpyViewProcesses( RMemSpySession& aEngine, MMemSpyViewObserver& aObserver, TProcessId aId )
+: CMemSpyViewBase( aEngine, aObserver ), iCurrentProcessId( aId )
+ {
+ }
+
+CMemSpyViewProcesses::~CMemSpyViewProcesses()
+ {
+ iProcesses.Close();
+ delete iSearchField;
+ delete iMatcherBuffer;
+ }
+
+
+//void CMemSpyViewProcesses::ConstructL( const TRect& aRect, CCoeControl& aContainer, TAny* aSelectionRune )
+void CMemSpyViewProcesses::ConstructL( const TRect& aRect, CCoeControl& aContainer, TProcessId aSelectionRune )
+ {
+ iMemSpySession.GetProcessesL(iProcesses); // get processes array;
+
+ _LIT( KTitle, "Processes\n& Threads" );
+ SetTitleL( KTitle );
+ //
+ //CMemSpyViewBase::ConstructL( aRect, aContainer, aSelectionRune );
+ CMemSpyViewBase::ConstructL( aRect, aContainer );
+ //
+ iMatcherBuffer = HBufC::NewL( KMemSpyMaxSearchTextLengthWithWildcards );
+ //
+ iSearchField = CAknSearchField::NewL( *this, CAknSearchField::ESearch, NULL, KMemSpyMaxSearchTextLength );
+
+ iSearchField->SetObserver( this );
+ iSearchField->SetFocus( ETrue );
+ iSearchField->SetComponentsToInheritVisibility( ETrue );
+ //
+ if ( iCurrentProcessId > 0 )
+ {
+ TInt index = 0;
+ // TProcessId selectedItem = aSelectionRune; //static_cast< TProcessId >( *aSelectionRune );
+ for( TInt i=0; i<iProcesses.Count();i++)
+ {
+ if( iProcesses[i]->Id() == iCurrentProcessId )
+ {
+ index = i;
+ }
+ }
+
+ if ( index >= 0 && index < iListBox->Model()->NumberOfItems() )
+ {
+ iListBox->SetCurrentItemIndex( index );
+ HandleListBoxItemSelectedL( index );
+ }
+ }
+ else if ( iProcesses.Count() > 0 )
+ {
+ iListBox->SetCurrentItemIndex( 0 );
+ HandleListBoxItemSelectedL( 0 );
+ }
+ //
+ SizeChanged();
+ ActivateL();
+ }
+
+
+CMemSpyProcess& CMemSpyViewProcesses::CurrentProcess() const
+ {
+ /*
+ __ASSERT_ALWAYS( iCurrentProcess != NULL, User::Invariant() );
+ return *iCurrentProcess;
+ */
+ }
+
+
+void CMemSpyViewProcesses::RefreshL()
+ {
+ SetListBoxModelL();
+ CMemSpyViewBase::RefreshL();
+ }
+
+
+TMemSpyViewType CMemSpyViewProcesses::ViewType() const
+ {
+ return EMemSpyViewTypeProcesses;
+ }
+
+
+CMemSpyViewBase* CMemSpyViewProcesses::PrepareParentViewL()
+ {
+ CMemSpyViewMainMenu* parent = new(ELeave) CMemSpyViewMainMenu( iMemSpySession, iObserver );
+ CleanupStack::PushL( parent );
+ parent->ConstructL( Rect(), *Parent(), (TAny*) ViewType() );
+ CleanupStack::Pop( parent );
+ return parent;
+ }
+
+
+CMemSpyViewBase* CMemSpyViewProcesses::PrepareChildViewL()
+ {
+ CMemSpyViewThreads* child = new(ELeave) CMemSpyViewThreads( iMemSpySession, iObserver, iProcesses[iListBox->CurrentItemIndex()]->Id(), 0 );
+ CleanupStack::PushL( child );
+ child->ConstructL( Rect(), *Parent() );
+ CleanupStack::Pop( child );
+ return child;
+
+ return 0;
+ }
+
+
+void CMemSpyViewProcesses::DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane )
+ {
+ if ( aResourceId == MenuCascadeResourceId() )
+ {
+ CMemSpyProcess& process = CurrentProcess();
+ //const TBool hide = ( iEngine.Container().Count() == 0 ) || process.IsDead(); //TODO
+ //
+ const TBool hide = EFalse; //to replace
+
+ aMenuPane->SetItemDimmed( EMemSpyCmdProcessInfo, hide );
+ aMenuPane->SetItemDimmed( EMemSpyCmdProcessEnd, hide );
+ }
+ }
+
+
+TBool CMemSpyViewProcesses::HandleCommandL( TInt aCommand )
+ {
+ TBool handled = ETrue;
+ //
+ switch ( aCommand )
+ {
+ // Sorting
+ case EMemSpyCmdProcessSortById:
+ OnCmdSortByIdL();
+ break;
+ case EMemSpyCmdProcessSortByName:
+ OnCmdSortByNameL();
+ break;
+ case EMemSpyCmdProcessSortByThreadCount:
+ OnCmdSortByThreadCountL();
+ break;
+ case EMemSpyCmdProcessSortByCodeSegs:
+ OnCmdSortByCodeSegsL();
+ break;
+ case EMemSpyCmdProcessSortByHeapUsage:
+ OnCmdSortByHeapUsageL();
+ break;
+ case EMemSpyCmdProcessSortByStackUsage:
+ OnCmdSortByStackUsageL();
+ break;
+ // End
+ case EMemSpyCmdProcessEndTerminate:
+ OnCmdEndTerminateL();
+ break;
+ case EMemSpyCmdProcessEndKill:
+ OnCmdEndKillL();
+ break;
+ case EMemSpyCmdProcessEndPanic:
+ OnCmdEndPanicL();
+ break;
+ // Info
+ case EMemSpyCmdProcessInfoSummary:
+ OnCmdInfoSummaryL();
+ break;
+ case EMemSpyCmdProcessInfoHandles:
+ OnCmdInfoHandlesL();
+ break;
+
+ default:
+ handled = CMemSpyViewBase::HandleCommandL( aCommand );
+ break;
+ }
+ //
+ return handled;
+ }
+
+
+void CMemSpyViewProcesses::OnCmdSortByIdL()
+ {
+ //iEngine.Container().SortById();
+ RefreshL();
+ }
+
+
+void CMemSpyViewProcesses::OnCmdSortByNameL()
+ {
+ //iEngine.Container().SortByName();
+ RefreshL();
+ }
+
+
+void CMemSpyViewProcesses::OnCmdSortByThreadCountL()
+ {
+ //iEngine.Container().SortByThreadCount();
+ RefreshL();
+ }
+
+
+void CMemSpyViewProcesses::OnCmdSortByCodeSegsL()
+ {
+ //iEngine.Container().SortByCodeSegs();
+ RefreshL();
+ }
+
+
+void CMemSpyViewProcesses::OnCmdSortByHeapUsageL()
+ {
+ //iEngine.Container().SortByHeapUsage();
+ RefreshL();
+ }
+
+
+void CMemSpyViewProcesses::OnCmdSortByStackUsageL()
+ {
+ // iEngine.Container().SortByStackUsage();
+ RefreshL();
+ }
+
+
+void CMemSpyViewProcesses::OnCmdInfoSummaryL()
+ {
+ //CMemSpyProcess& process = CurrentProcess();
+ //iEngine.HelperProcess().OutputProcessInfoL( process );
+ }
+
+
+void CMemSpyViewProcesses::OnCmdInfoHandlesL()
+ {
+ /*
+ CMemSpyProcess& process = CurrentProcess();
+ //
+ const TInt threadCount = process.Count();
+ for( TInt i=0; i<threadCount; i++ )
+ {
+ CMemSpyThread& thread = process.At( i );
+ thread.InfoContainerForceSyncronousConstructionL().PrintL();
+ }
+ */
+ }
+
+
+void CMemSpyViewProcesses::OnCmdEndTerminateL()
+ {
+ /*
+ TBool doTerminate = ETrue;
+ CMemSpyProcess& process = CurrentProcess();
+ //
+ if ( process.IsSystemPermanent() || process.IsSystemCritical() )
+ {
+ CAknQueryDialog* importDialog = CAknQueryDialog::NewL();
+ doTerminate = ( importDialog->ExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) );
+ }
+ //
+ if ( doTerminate )
+ {
+ process.TerminateL();
+ RefreshL();
+ }
+ */
+ }
+
+
+void CMemSpyViewProcesses::OnCmdEndPanicL()
+ {/*
+ TBool doTerminate = ETrue;
+ CMemSpyProcess& process = CurrentProcess();
+ //
+ if ( process.IsSystemPermanent() || process.IsSystemCritical() )
+ {
+ CAknQueryDialog* importDialog = CAknQueryDialog::NewL();
+ doTerminate = ( importDialog->ExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) );
+ }
+ //
+ if ( doTerminate )
+ {
+ process.PanicL();
+ RefreshL();
+ }
+ */
+ }
+
+
+void CMemSpyViewProcesses::OnCmdEndKillL()
+ {/*
+ TBool doTerminate = ETrue;
+ CMemSpyProcess& process = CurrentProcess();
+ //
+ if ( process.IsSystemPermanent() || process.IsSystemCritical() )
+ {
+ CAknQueryDialog* importDialog = CAknQueryDialog::NewL();
+ doTerminate = ( importDialog->ExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) );
+ }
+ //
+ if ( doTerminate )
+ {
+ process.KillL();
+ RefreshL();
+ }
+ */
+ }
+
+
+
+
+void CMemSpyViewProcesses::SetListBoxModelL()
+ {
+ if( iProcesses.Count() > 0 )
+ {
+ iProcesses.Close();
+ }
+
+ iMemSpySession.GetProcessesL(iProcesses); // get processes array;
+ iModel = new (ELeave) CDesC16ArrayFlat( iProcesses.Count() + 1); //array for formated items
+
+ _LIT( KTab, "\t" );
+ iModel = FormatModel( iProcesses ); //TODO Format model method with advanced formatting
+
+ /*
+ for( TInt i=0; i < iProcesses.Count(); i++ )
+ {
+ HBufC* tempName = HBufC::NewL( iProcesses[i]->Name().Length() + 16 );
+ CleanupStack::PushL( tempName );
+ TPtr tempNamePtr( tempName->Des() );
+ tempNamePtr.Copy( KTab );
+ tempNamePtr.Append( iProcesses[i]->Name() );
+ iModel->AppendL( tempNamePtr );
+
+ CleanupStack::PopAndDestroy( tempName );
+ }
+ */
+ CAknSettingStyleListBox* listbox = static_cast< CAknSettingStyleListBox* >( iListBox );
+ //listbox->Model()->SetItemTextArray( &iEngine.Container() );
+ listbox->Model()->SetItemTextArray( iModel );
+ listbox->Model()->SetOwnershipType( ELbmDoesNotOwnItemArray );
+ }
+
+
+void CMemSpyViewProcesses::HandleListBoxItemActionedL( TInt /*aIndex*/ )
+ {
+ // Notify observer about an item being 'fired'
+ ReportEventL( MMemSpyViewObserver::EEventItemActioned );
+ }
+
+
+void CMemSpyViewProcesses::HandleListBoxItemSelectedL( TInt aIndex )
+ {/*
+ if ( iCurrentProcess )
+ {
+ iCurrentProcess->Close();
+ }
+
+ // Obtain the process that corresponds to the selected item
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess& process = container.At( aIndex );
+ iCurrentProcess = &process;
+ iCurrentProcess->Open();
+
+ // Notify observer about item selection
+ ReportEventL( MMemSpyViewObserver::EEventItemSelected );*/
+ }
+
+
+void CMemSpyViewProcesses::SizeChanged()
+ {
+ const TRect rect( Rect() );
+
+ if ( iListBox && iSearchField )
+ {
+ const TInt lafIndex_H = 1;
+ AknLayoutUtils::LayoutControl( iListBox, rect, AknLayout::list_gen_pane( lafIndex_H ) );
+ AknLayoutUtils::LayoutControl( iSearchField, rect, AknLayout::find_pane() );
+ }
+ else
+ {
+ CMemSpyViewBase::SizeChanged();
+ }
+
+/*
+ // Search field
+ TSize searchFieldSize( iSearchField->MinimumSize() ); // BALLS: search field doesn't implement minimum size correctly?!?!?
+ searchFieldSize.SetWidth( rect.Width() );
+ const TRect searchFieldRect( TPoint( rect.iTl.iX, rect.iBr.iY ), searchFieldSize );
+ iSearchField->SetRect( searchFieldRect );
+
+ // Listbox
+ TSize listBoxSize( rect.Size() - TSize( 0, searchFieldSize.iHeight ) );
+ iListBox->SetRect( rect.iTl, listBoxSize );
+*/
+ }
+
+
+TInt CMemSpyViewProcesses::CountComponentControls() const
+ {
+ TInt count = 0;
+ //
+ if ( iListBox != NULL )
+ {
+ ++count;
+ }
+ if ( iSearchField != NULL )
+ {
+ ++count;
+ }
+ //
+ return count;
+ }
+
+
+CCoeControl* CMemSpyViewProcesses::ComponentControl( TInt aIndex ) const
+ {
+ CCoeControl* ret = iListBox;
+ //
+ if ( aIndex == 1 )
+ {
+ ret = iSearchField;
+ }
+ //
+ return ret;
+ }
+
+
+TKeyResponse CMemSpyViewProcesses::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType )
+ {
+ TKeyResponse resp = EKeyWasNotConsumed;
+ //
+ if ( aType == EEventKey )
+ {
+ switch( aKeyEvent.iCode )
+ {
+ case EKeyUpArrow:
+ case EKeyDownArrow:
+ case EKeyEnter:
+ case EKeyOK:
+ if ( iListBox )
+ {
+ resp = iListBox->OfferKeyEventL( aKeyEvent, aType );
+ }
+ break;
+ default:
+ break;
+ }
+ //
+ if ( resp == EKeyWasNotConsumed )
+ {
+ // Do we need to show the find field?
+ resp = iSearchField->OfferKeyEventL( aKeyEvent, aType );
+ }
+ }
+ //
+ return resp;
+ }
+
+
+void CMemSpyViewProcesses::HandleControlEventL( CCoeControl* aControl, TCoeEvent aEventType )
+ {
+ CMemSpyViewBase::HandleControlEventL( aControl, aEventType );
+ //
+ if ( aEventType == MCoeControlObserver::EEventStateChanged )
+ {
+ if ( aControl == iSearchField )
+ {
+ SelectListBoxItemByFindTextL();
+ }
+ }
+ }
+
+
+void CMemSpyViewProcesses::FocusChanged( TDrawNow /*aDrawNow*/ )
+ {
+ if ( iListBox )
+ {
+ iListBox->SetFocus( IsFocused() );
+ }
+ if ( iSearchField )
+ {
+ iSearchField->SetFocus( IsFocused() );
+ }
+ }
+
+
+void CMemSpyViewProcesses::SelectListBoxItemByFindTextL()
+ {
+ /*
+ _LIT( KMemSpyWildcardCharacter, "*" );
+
+ TPtr pBuffer( iMatcherBuffer->Des() );
+ iSearchField->GetSearchText( pBuffer );
+ //pBuffer.Insert( 0, KMemSpyWildcardCharacter );
+ pBuffer.Append( KMemSpyWildcardCharacter );
+
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ const TInt count = container.Count();
+ //
+ TInt index = 0;
+ while( index < count )
+ {
+ CMemSpyProcess& process = container.At( index );
+ const TPtrC processName( process.Name() );
+ //
+ if ( processName.MatchF( pBuffer ) >= 0 )
+ {
+ HandleListBoxItemSelectedL( index );
+ iListBox->ScrollToMakeItemVisible( index );
+ iListBox->SetCurrentItemIndexAndDraw( index );
+ return;
+ }
+
+ ++index;
+ }
+ */
+ }
+
+//Model formating methods
+//TODO: to be debbuged
+
+CDesCArrayFlat* CMemSpyViewProcesses::FormatModel( RArray<CMemSpyApiProcess*> aProcesses )
+ {
+ model = new (ELeave) CDesC16ArrayFlat( iProcesses.Count() + 16 ); //array for formated items
+ _LIT( KMemSpyProcessNameFormatSpecBasicName, " \t%S\t\t%8x, " );
+
+ for( TInt i=0; i < aProcesses.Count(); i++ )
+ {
+ HBufC* tempName = HBufC::NewL( KMaxFullName ); //aProcesses[i]->Name().Length() + 16
+ CleanupStack::PushL( tempName );
+ TPtr tempNamePtr( tempName->Des() );
+ tempNamePtr.Copy( aProcesses[i]->Name() );
+
+ TBuf<10> priority;
+ TProcessPriority tempPriority = aProcesses[i]->Priority();
+ MemSpyUiUtils::AppendPriority( priority, tempPriority );
+
+ // Convert the full name to the format we want in the UI
+ TBuf<KMaxFullName + 60> name;
+ TMemSpyTruncateOverflow overflow; //included from EngineUtils TODO: to consider if this is needed to be removed or left there
+ TUint32 tempSID = aProcesses[i]->SID();
+ name.AppendFormat( KMemSpyProcessNameFormatSpecBasicName, &overflow, tempName, tempSID ); //tempNamePtr
+
+ if( aProcesses[i]->ExitType() != EExitPending ) // instead of IsDead() method
+ {
+ MemSpyUiUtils::AppendExitInfo( name, aProcesses[i]->ExitType(), aProcesses[i]->ExitReason(), aProcesses[i]->ExitCategory() );
+ }
+ else
+ {
+ _LIT( KMemSpyProcessNameFormatSpecAlive, "%2d thr, %S" );
+ name.AppendFormat( KMemSpyProcessNameFormatSpecAlive, &overflow, aProcesses[i]->ThreadCount(), &priority );
+ }
+
+ model->AppendL( name );
+
+ CleanupStack::PopAndDestroy( tempName );
+ }
+
+ return model;
+ }
+/*
+void CMemSpyViewProcesses::AppendPriority( TDes& aDes, TProcessPriority aPriority )
+ {
+ switch( aPriority )
+ {
+ case EPriorityLow:
+ aDes += _L("[L]");
+ break;
+ case EPriorityBackground:
+ aDes += _L("[B]");
+ break;
+ case EPriorityForeground:
+ aDes += _L("[F]");
+ break;
+ case EPriorityHigh:
+ aDes += _L("[H]");
+ break;
+ case EPriorityWindowServer:
+ aDes += _L("[WS]");
+ break;
+ case EPriorityFileServer:
+ aDes += _L("[FS]");
+ break;
+ case EPriorityRealTimeServer:
+ aDes += _L("[RTS]");
+ break;
+ case EPrioritySupervisor:
+ aDes += _L("[SUP]");
+ break;
+ default:
+ aDes += _L("[?]");
+ break;
+ }
+ }
+
+void CMemSpyViewProcesses::AppendExitInfo( TDes& aDes, TExitType aType, TInt aExitReason, const TDesC& aExitCategory )
+ {
+ aDes.Append( '[' );
+ const TInt length = aDes.Length();
+ AppendExitType( aDes, aType );
+ aDes.SetLength( length + 1 ); // Remove all but the first letter
+ aDes.Append( ']' );
+
+ if ( aType == EExitKill || aType == EExitPending )
+ {
+ // Kill implies "clean" exit. Pending implies not yet dead.
+ }
+ else
+ {
+ TMemSpyTruncateOverflow overflow;
+
+ // Terminate or Panic implies abnormal exit condition, so
+ // show full exit info.
+ _LIT( KAbnormalFormatSpec, " %S-%d" );
+ aDes.AppendFormat( KAbnormalFormatSpec, &overflow, &aExitCategory, aExitReason );
+ }
+ }
+*/
+/*
+void CMemSpyViewProcesses::AppendExitType( TDes& aDes, TExitType aType )
+ {
+ _LIT( KExitTypeKilled, "Killed" );
+ _LIT( KExitTypeTerminated, "Terminated" );
+ _LIT( KExitTypePanicked, "Panicked" );
+ _LIT( KExitTypePending, "Pending" );
+
+ // Panic and Terminate are exceptional exit conditions.
+ // Kill, is ironically, not an exceptional condition.
+ switch( aType )
+ {
+ case EExitKill:
+ aDes += KExitTypeKilled;
+ break;
+ case EExitTerminate:
+ aDes += KExitTypeTerminated;
+ break;
+ case EExitPanic:
+ aDes += KExitTypePanicked;
+ break;
+ default:
+ case EExitPending:
+ aDes += KExitTypePending;
+ break;
+ }
+ }
+*/
+