--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspyui/ui/avkon/src/MemSpyViewProcesses.cpp Wed Sep 15 12:13:45 2010 +0300
@@ -0,0 +1,604 @@
+/*
+* 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 );
+ //
+ /* TODO: to restore the Search field functionality
+ 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() )
+ {
+ TInt index = iListBox->CurrentItemIndex( );
+ const TBool hide = iProcesses[index]->IsDead() || iProcesses[index]->ThreadCount() == 0;
+
+ //aMenuPane->SetItemDimmed( EMemSpyCmdProcessInfo, hide ); //to be added into API
+ 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 system = ETrue;
+ TBool doTerminate = ETrue;
+ TInt err = KErrNone;
+
+ iMemSpySession.ProcessSystemPermanentOrCritical( iCurrentProcessId, system );
+
+ if ( system )
+ {
+ CAknQueryDialog* importDialog = CAknQueryDialog::NewL();
+ doTerminate = ( importDialog->ExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) );
+ }
+
+ if ( doTerminate )
+ {
+ TRAP( err, iMemSpySession.EndProcessL( iCurrentProcessId, ETerminate ) );
+ if( err = KErrNone )
+ RefreshL();
+ }
+ }
+
+
+void CMemSpyViewProcesses::OnCmdEndPanicL()
+ {
+ TBool system = ETrue;
+ TBool doTerminate = ETrue;
+ TInt err = KErrNone;
+
+ iMemSpySession.ProcessSystemPermanentOrCritical( iCurrentProcessId, system );
+
+ if ( system )
+ {
+ CAknQueryDialog* importDialog = CAknQueryDialog::NewL();
+ doTerminate = ( importDialog->ExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) );
+ }
+
+ if ( doTerminate )
+ {
+ TRAP( err, iMemSpySession.EndProcessL( iCurrentProcessId, EPanic ) );
+ if( err == KErrNone )
+ RefreshL();
+ }
+ }
+
+
+void CMemSpyViewProcesses::OnCmdEndKillL()
+ {
+ TBool system = ETrue;
+ TBool doTerminate = ETrue;
+ TInt err = KErrNone;
+
+ iMemSpySession.ProcessSystemPermanentOrCritical( iCurrentProcessId, system );
+
+ if ( system )
+ {
+ CAknQueryDialog* importDialog = CAknQueryDialog::NewL();
+ doTerminate = ( importDialog->ExecuteLD( R_MEMSPY_PANIC_SYSTEM_CRITICAL_THREAD_OR_PROCESS ) );
+ }
+
+ if ( doTerminate )
+ {
+ TRAP( err, iMemSpySession.EndProcessL( iCurrentProcessId, EKill ) )
+ if( err == KErrNone )
+ 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
+
+ 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 )
+ {
+ iCurrentProcessId = iProcesses[aIndex]->Id();
+ /*
+ if ( iCurrentProcess )
+ {
+ iCurrentProcess->Close();
+ }
+
+ // Obtain the process that corresponds to the selected item
+ CMemSpyEngineObjectContainer& container = iEngine.Container();
+ CMemSpyProcess& process = container.At( aIndex );
+ iCurrentProcess = &process;
+
+ // Notify observer about item selection
+ */
+ ReportEventL( MMemSpyViewObserver::EEventItemSelected );
+ }
+
+
+void CMemSpyViewProcesses::SizeChanged()
+ {
+ const TRect rect( Rect() );
+ CMemSpyViewBase::SizeChanged();
+ /*
+ 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;
+ }
+
+