piprofiler/engine/src/SamplerController.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 16:17:58 +0300
branchRCL_3
changeset 59 8ad140f3dd41
parent 49 7fdc9a71d314
permissions -rw-r--r--
Revision: 201039 Kit: 201041

/*
* 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 "SamplerController.h"
//#include <piprofiler/EngineUIDs.h>

// CONSTANTS
const TInt KMaxSamplerPluginCount = 20;
const TInt KMaxExtraSettingsItemCount = 6;

// LITERALS
_LIT8(KSamplingPeriod, "sampling_period_ms");
_LIT8(KNewLine8, "\n");
_LIT8(KEquals8, "=");
_LIT8(KSettingsText, " settings");
_LIT(KNewLine, "\n");
_LIT(KEquals, "=");
_LIT(KCommentSeparator, " ; ");

CSamplerController* CSamplerController::NewL(CProfilerSampleStream& aStream)
    {
    CSamplerController* self = new( ELeave ) CSamplerController(aStream);
    CleanupStack::PushL( self );
    self->ConstructL( );
    CleanupStack::Pop( self );
    return self;
    }

void CSamplerController::ConstructL()
	{
	// initiate sampler plugin list
	InitialiseSamplerListL();
	}


CSamplerController::CSamplerController(CProfilerSampleStream& aStream) : 
    iStream(aStream)
	{
	}

void CSamplerController::InitialiseSamplerListL()
    {
    // create new sampler plugin array
    iPluginArray = new (ELeave) CArrayPtrFlat<CSamplerPluginInterface>( KMaxSamplerPluginCount );
    
    // create plugin loader instance
    iPluginLoader = CSamplerPluginLoader::NewL();
    
    // register sampler controller to get notifications of succesfull plugin load
    iPluginLoader->SetObserver( this );
    
    // load sampler plugins asynchronously
    iPluginLoader->LoadAsyncL( iPluginArray );
    
    LOGTEXT(_L(" RSamplerController::InitialiseUserSideSamplerList - exit"));	
    }

CSamplerController::~CSamplerController()
	{
	LOGTEXT(_L("CSamplerController::~CSamplerController - entry" ));
	
    if ( iPluginArray )
        {
        // destroy the plugin instances
        // empty loaded plugins from array
        for(TInt i(0);i<iPluginArray->Count();i++)
            {
            if(iPluginArray->At(i))
                {
                delete iPluginArray->At(i);
                iPluginArray->At(i) = NULL;
                }
            }
        iPluginArray->Reset();
        delete iPluginArray;
        iPluginArray = NULL;
        }
	
	if ( iPluginLoader )
	    {
	    iPluginLoader->AbortAsyncLoad();
	    delete iPluginLoader;
	    iPluginLoader = NULL;
	    }
    
	LOGTEXT(_L("CSamplerController::~CSamplerController - exit" ));
	}

void CSamplerController::SetObserver(MSamplerControllerObserver* aObserver)
    {
    iObserver = aObserver;
    }
    
TInt CSamplerController::UpdateSavedSamplerAttributesL(CDesC8ArrayFlat* aSavedLineArray, CArrayFixFlat<TSamplerAttributes>* aAttributes)
    {
    TInt err(KErrNone);
    TInt count(iPluginArray->Count());
    // all plugins get their own settings among whole lump of setting strings
    CSamplerPluginInterface* plugin = NULL;
    
    // loop through the plugin array
    for(TInt i(0);i<count;i++)
        {
        // get each plugin at a time
        plugin = iPluginArray->At(i);
        
        // call each plugin to sort out its own settings 
        err = plugin->ConvertRawSettingsToAttributes(aSavedLineArray);
        
        // get plugin specific attributes, array may contain attributes of several sub samplers
        plugin->GetAttributesL(aAttributes); 
        }
    
    return err;
    }

TInt CSamplerController::SetSamplerSettingsL(TInt aUid, TSamplerAttributes aAttributes)
    {
    // parse right plugin based on UID
    CSamplerPluginInterface* plugin = GetPlugin(TUid::Uid(aUid));
    
    // set the sampler attributes of a sampler plugin
    plugin->SetAttributesL(aAttributes);
    
    return KErrNone;
    }

void CSamplerController::GetSamplerAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
    {
    CSamplerPluginInterface* plugin = NULL;
    
    TInt count(iPluginArray->Count());
    
    // get first all the attributes from all the sampler plugins listed in iPluginArray
    for(TInt i(0);i<count;i++)
        {
        // get the plugin first
        plugin = iPluginArray->At(i);
        
        // get plugin specific attributes, array may contain attributes of several sub samplers
        plugin->GetAttributesL(aAttributes); 
        }
    }

void CSamplerController::ComposeAttributesToSettingsFileFormat(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttributes)
    {
    // write immediately to settings file
    ComposeSettingsText(aFile, aAttributes);
    }

void CSamplerController::ComposeSettingsText(RFile& aFile, CArrayFixFlat<TSamplerAttributes>* aAttrArray)
    {
    // temporary buffer for a setting line
    TBuf<384> settingLine;
    TBuf8<384> settingLine8;
    TInt itemCount(0);
    TBuf<266> tBuf;
    
    TSamplerAttributes attr;
    
    for(TInt i(0);i<aAttrArray->Count();i++)
        {
        // get the attribute container 
        attr = aAttrArray->At(i);
        
        // add the name and description of the sampler in brackets first
        settingLine8.Copy(KBracketOpen);
        settingLine8.Append(attr.iShortName);
        settingLine8.Append(KBracketClose);
        settingLine8.Append(KCommentSeparator());
        settingLine8.Append(attr.iName);
        settingLine8.Append(KSettingsText);
        settingLine8.Append(KNewLine8);
        aFile.Write(settingLine8);
        
        // enabled
        settingLine8.Copy(KEnabled);
        settingLine8.Append(KEquals8);
        settingLine8.Append(Bool2Str(attr.iEnabled));
        settingLine8.Append(KNewLine8);
        aFile.Write(settingLine8);
        
        // sampling rate (if set)
        if( attr.iSampleRate != -1 )
            {
            settingLine8.Copy(KSamplingPeriod);
            settingLine8.Append(KEquals8);
            settingLine8.Append(Int2Str(attr.iSampleRate));
            settingLine8.Append(KNewLine8);
            aFile.Write(settingLine8);
            }
        
        itemCount = attr.iItemCount;
        
        // check if item count set is sane, max extra settings item count 6
        if(itemCount > KMaxExtraSettingsItemCount)
            {
            // probably forgot to set the item count value in plugin => safe to set it 0
            itemCount = 0;
            }
        
        // setting items
        for (TInt j(0);j<itemCount;j++)
            {
            switch(j)
                {
                case 0: // settingItem1
                    {
                    settingLine.Copy(attr.iSettingItem1.iSettingText);
                    settingLine.Append(KEquals());
                    settingLine.Append(attr.iSettingItem1.iValue);
                    settingLine.Append(KCommentSeparator());
                    settingLine.Append(attr.iSettingItem1.iUIText);
                    settingLine.Append(KNewLine());
                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
                    aFile.Write(settingLine8);
                    break;
                    }
                case 1: // settingItem2
                    {
                    settingLine.Copy(attr.iSettingItem2.iSettingText);
                    settingLine.Append(KEquals());
                    settingLine.Append(attr.iSettingItem2.iValue);
                    settingLine.Append(KCommentSeparator());
                    settingLine.Append(attr.iSettingItem2.iUIText);
                    settingLine.Append(KNewLine());
                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
                    aFile.Write(settingLine8);
                    break;
                    }
                case 2: // settingItem3
                    {
                    settingLine.Copy(attr.iSettingItem3.iSettingText);
                    settingLine.Append(KEquals());
                    settingLine.Append(attr.iSettingItem3.iValue);
                    settingLine.Append(KCommentSeparator());
                    settingLine.Append(attr.iSettingItem3.iUIText);
                    settingLine.Append(KNewLine());
                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
                    aFile.Write(settingLine8);
                    break;
                    }
                case 3: // settingItem4
                    {
                    settingLine.Copy(attr.iSettingItem4.iSettingText);
                    settingLine.Append(KEquals());
                    settingLine.Append(attr.iSettingItem4.iValue);
                    settingLine.Append(KCommentSeparator());
                    settingLine.Append(attr.iSettingItem4.iUIText);
                    settingLine.Append(KNewLine());
                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
                    aFile.Write(settingLine8);
                    break;
                    }
                case 4: // settingItem5
                    {
                    settingLine.Copy(attr.iSettingItem5.iSettingText);
                    settingLine.Append(KEquals());
                    settingLine.Append(attr.iSettingItem5.iValue);
                    settingLine.Append(KCommentSeparator());
                    settingLine.Append(attr.iSettingItem5.iUIText);
                    settingLine.Append(KNewLine());
                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
                    aFile.Write(settingLine8);
                    break;
                    }
                case 5: // settingItem6
                    {
                    settingLine.Copy(attr.iSettingItem6.iSettingText);
                    settingLine.Append(KEquals());
                    settingLine.Append(attr.iSettingItem6.iValue);
                    settingLine.Append(KCommentSeparator());
                    settingLine.Append(attr.iSettingItem6.iUIText);
                    settingLine.Append(KNewLine());
                    CnvUtfConverter::ConvertFromUnicodeToUtf8(settingLine8, settingLine);
                    aFile.Write(settingLine8);
                    break;
                    }
                }
            }
        }
    }

// ----------------------------------------------------------------------------
// Converts given descriptor into TBool value.
// ----------------------------------------------------------------------------
//
inline void CSamplerController::Str2Bool(const TDesC8& aBuf, TBool& aValue)
    {
    if (aBuf.CompareF(KFalse) == 0)
        aValue = EFalse;
    else
        aValue = ETrue;
    }

// ----------------------------------------------------------------------------
// Converts given descriptor into TInt value.
// ----------------------------------------------------------------------------
//
inline void CSamplerController::Str2Int(const TDesC8& aBuf, TInt& aValue)
    {
    TLex8 conv;
    conv.Assign(aBuf);
    
    if (conv.Val(aValue) != KErrNone)
        aValue = 0;
    }

// ----------------------------------------------------------------------------
// Converts given descriptor into TInt value.
// ----------------------------------------------------------------------------
//
inline void CSamplerController::Str2Int(const TDesC8& aBuf, TUint32& aValue)
    {
    TInt temp(0);
    
    TLex8 conv;
    conv.Assign(aBuf);
    
    if (conv.Val(temp) != KErrNone)
        aValue = 0;
    else
        aValue = (TUint32)temp;
    }

// ----------------------------------------------------------------------------
// Converts given boolean into a descriptor.
// ----------------------------------------------------------------------------
//
inline TBuf8<16> CSamplerController::Bool2Str(const TBool& aValue)
    {
    TBuf8<16> buf;
    
    if (aValue)
        buf.Copy(KTrue);
    else
        buf.Copy(KFalse);
    
    return buf;
    }

// ----------------------------------------------------------------------------
// Converts given integer into a descriptor.
// ----------------------------------------------------------------------------
//
inline TBuf8<16> CSamplerController::Int2Str(const TInt& aValue)
    {
    TBuf8<16> buf;
    buf.AppendNum(aValue);
   
    return buf;
    }


void CSamplerController::HandlePluginLoaded( KSamplerPluginLoaderStatus aStatus )
    {
    
    // process status value
    switch(aStatus)
        {
        case 0:
            LOGSTRING2("RSamplerController - one plugin loaded, status: %d", aStatus);
            break;
        case 1:
            LOGSTRING2("RSamplerController - a plugin load failed: %d", aStatus);
            break;
        case 2:
            LOGSTRING2("RSamplerController - plugin loading aborted: %d", aStatus);
            break;
        case 3:
            LOGSTRING2("RSamplerController - all plugins loaded: %d", aStatus);
            TRAPD(err, iPluginLoader->SortPluginsL(iPluginArray));
            if(err != KErrNone)
                {
                LOGTEXT(_L("Sampler controller unable to sort plugins"));
                }
            
            // call engine to finalize the startup
            TRAPD(result, iObserver->HandleSamplerControllerReadyL(););
            if(result != KErrNone)
                {
                LOGTEXT(_L("Failed to notify engine"));
                }
            break;
        case 4:
            LOGSTRING2("RSamplerController - error in loading plugins: %d", aStatus);
            break;
        default:
            break;
        }
    }


CSamplerPluginInterface* CSamplerController::GetPlugin(TUid aUid)
	{
	LOGTEXT(_L("RSamplerController::GetPlugin - entry"));
	// check that plugin array contains samplers
	if( iPluginArray && iPluginArray->Count() > 0 )
	  {
    	for(TInt i=0;i<iPluginArray->Count();i++)
    		{
	    	CSamplerPluginInterface* plugin = iPluginArray->At(i);
	    	TUid uid = plugin->Id(-1);	// get parent uid first
	    	if(uid == aUid)
	    		{
	    		LOGTEXT(_L("CSamplerController::GetPlugin() - main plug-in found!"));
    			return plugin;
				} 

            if(plugin->SubId(aUid) != KErrNotFound)
                {
                LOGTEXT(_L("CSamplerController::GetPlugin() - subsampler found!"));
                return plugin;
                }
    		}
		}	
	LOGTEXT(_L("CSamplerController::GetPlugin() - No plug-in found for UID"));

	return (CSamplerPluginInterface*)0;
	}

// start user mode samplers
void CSamplerController::StartSamplerPluginsL()
    {
    CSamplerPluginInterface* plugin = NULL;

	if( iPluginArray )
		{
		TInt count(iPluginArray->Count());
	
		for(TInt i(0);i<count;i++)
			{
			plugin = iPluginArray->At(i);
			// check if some error received when starting profiling
			TRAPD(err, plugin->ResetAndActivateL(iStream));
			LOGSTRING2(" RSamplerController::StartSamplerPlugin - plugin activated (0x%X)", plugin->Id(-1));  
			if( err != KErrNone)
				{
				LOGSTRING2(" RSamplerController::StartSamplerPlugin - error %d", i);  
				// handle received error, need to update UI!
				iObserver->HandleError(err);
				}
            }
	    }
    }

// stop user mode samplers
TInt CSamplerController::StopSamplerPlugins()
	{
	TInt count(0);

	if( iPluginArray && iPluginArray->Count() > 0 )
		{
		TInt i(0);
		CSamplerPluginInterface* plugin = NULL;
		// stop kernel mode samplers
    	for(;i<iPluginArray->Count();i++)
    		{
			plugin = iPluginArray->At(i); 
			TUint32 id = plugin->Id(-1).iUid;
            LOGSTRING2(" CSamplerController::StopSamplerPlugins - traceId = %d",
                        id);
            // stop only started samplers
            if(plugin->Enabled())
                {
                // stop selected plugin
                plugin->StopSampling();
                // check if user mode sampler, special flush needed to direct data to stream
                if(plugin->GetSamplerType() == PROFILER_USER_MODE_SAMPLER)
                    {
                    LOGTEXT(_L(" CSamplerController::StopSamplerPlugins - flushing user mode sampler stream"));
                    plugin->Flush();
                    }
                }
            count++;
    		}
		}
	return count; 	
	}

// end of file