memspyui/ui/avkon/src/MemSpyViewProcesses.cpp
branchRCL_3
changeset 50 9b2cffad4b5e
--- /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;
+	}
+
+