piprofiler/plugins/BUPplugin/src/BupPlugin.cpp
branchRCL_3
changeset 19 da2cedce4920
child 49 7fdc9a71d314
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/BUPplugin/src/BupPlugin.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,582 @@
+/*
+* 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 "BupPlugin.h"	
+//#include <piprofiler/EngineUIDs.h>
+
+#include <w32std.h> 	// for listening key events
+
+	
+// LITERALS
+// CONSTANTS
+const TUid KSamplerBupPluginUid = { 0x2001E5B6 };
+
+/*
+ *	
+ *	class CBupPlugin implementation
+ * 
+ */
+
+CBupPlugin* CBupPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/)
+	{
+	LOGTEXT(_L("CBupPlugin::NewL() - entry"));
+    CBupPlugin* self = new (ELeave) CBupPlugin();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CBupPlugin::NewL() - exit"));
+    return self;
+	}
+
+CBupPlugin::CBupPlugin() :
+	iVersionDescriptor(&(this->iVersion[1]),0,19), 	
+	iSamplerType(PROFILER_USER_MODE_SAMPLER)
+	{
+	iSamplerId = PROFILER_BUP_SAMPLER_ID;
+    iEnabled = EFalse;
+	LOGTEXT(_L("CBupPlugin::CBupPlugin() - konstruktori"));
+	}
+
+void CBupPlugin::ConstructL() 
+	{
+	LOGTEXT(_L("CBupPlugin::ConstructL() - entry"));
+	
+	// initiate sampler attributes array
+	iSamplerAttributes = new(ELeave) CArrayFixFlat<TSamplerAttributes>(1); // only one sampler
+	
+	// insert default attributes to array
+	InitiateSamplerAttributesL();
+	
+	LOGTEXT(_L("CBupPlugin::ConstructL() - exit"));
+	}
+
+
+CBupPlugin::~CBupPlugin()
+	{
+	LOGTEXT(_L("CBupPlugin::~CBupPlugin() - entry"));
+	if(iButtonListener)
+	    {
+	    // check if button listener still running
+	    if(Enabled())
+	        {
+	        // stop profiling
+	        iButtonListener->Stop();
+	        }
+        delete iButtonListener;
+	    }
+	
+	if(iSamplerAttributes)
+	    {
+	    iSamplerAttributes->Reset();
+	    }
+    delete iSamplerAttributes;
+	
+	LOGTEXT(_L("CBupPlugin::~CBupPlugin() - exit"));
+	}
+
+TUid CBupPlugin::Id(TInt /*aUid*/) const
+	{
+    LOGSTRING2("CBupPlugin::Id():0x%X", KSamplerBupPluginUid.iUid );
+    return KSamplerBupPluginUid;
+	}
+
+void CBupPlugin::InitiateSamplerAttributesL()
+    {
+    // create sampler attribute container
+    TSamplerAttributes attr(KSamplerBupPluginUid.iUid,
+            KBUPShortName(),
+            KBUPLongName(),
+            KBUPDescription(),
+            -1,
+            ETrue,
+            EFalse,
+            0); // default item count
+    this->iSamplerAttributes->AppendL(attr);
+    }
+
+// returns setting array
+void CBupPlugin::GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
+    {
+    // append my own attributes to complete array, requested by profiler engine
+    aAttributes->AppendL(iSamplerAttributes->At(0));
+    }
+
+TInt CBupPlugin::SetAttributesL(TSamplerAttributes aAttributes)
+    {
+    TSamplerAttributes attr;
+
+    attr = iSamplerAttributes->At(0);
+    // if UIDs match replace the old 
+    if(attr.iUid == aAttributes.iUid)
+        {
+        // replace the old attribute container
+        iSamplerAttributes->Delete(0);
+        iSamplerAttributes->InsertL(0, aAttributes);
+        return KErrNone;
+        }
+    return KErrNotFound;
+    }
+
+/* 
+ * Method for parsing and transforming text array settings into TSamplerAttributes (per each sub sampler),
+ * called by CSamplerController class
+ * 
+ * @param array of raw text setting lines, e.g. [gpp]\nenabled=true\nsampling_period_ms=1\n
+ */
+TInt CBupPlugin::ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aAllSettingsArray)
+    {
+    // local literals
+    _LIT8(KBUPShort, "bup");
+
+    TInt err(KErrNone);
+    TBuf8<16> samplerSearchName;
+    samplerSearchName.Copy(KBUPShort);
+    
+    // get sampler specific settings  
+    err = DoSetSamplerSettings(aAllSettingsArray, samplerSearchName, 0);
+    
+    // returns KErrNone if settings found, otherwise KErrNotFound
+    return err;
+    }
+
+TInt CBupPlugin::DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex)
+    {
+    // 
+    TBuf8<16> samplerSearch;
+    samplerSearch.Copy(KBracketOpen);
+    samplerSearch.Append(aSamplerName);
+    samplerSearch.Append(KBracketClose);
+    
+    // read a line
+    for (TInt i(0); i<aAllSettings->MdcaCount(); i++)
+        {
+        // check if this line has a setting block start, i.e. contains [xxx] in it
+        if (aAllSettings->MdcaPoint(i).CompareF(samplerSearch) == 0)
+            {
+            // right settings block found, now loop until the next block is found
+            for(TInt j(i+1);j<aAllSettings->MdcaCount();j++)
+                {
+                // check if the next settings block was found
+                if(aAllSettings->MdcaPoint(j).Left(1).CompareF(KBracketOpen) != 0)
+                    {
+                    // save found setting value directly to its owners attributes
+                    SaveSettingToAttributes(aAllSettings->MdcaPoint(j), aIndex);
+                    }
+                else
+                    {
+                    // next block found, return KErrNone
+                    return KErrNone;
+                    }
+                }
+            }
+        }
+    
+    return KErrNotFound;
+    }
+
+/**
+ * Method for setting a specific descriptor (from settings file) to attribute structure
+ * 
+ * @param aSetting  
+ * @param aName  
+ */
+void CBupPlugin::SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex)
+    {
+    // find the equal mark from the setting line
+    TInt sepPos = aSetting.Find(KSettingItemSeparator);
+    // check that '=' is found
+    if (sepPos > 0)
+        {
+        // check that the element matches
+        if (aSetting.Left(sepPos).CompareF(KEnabled) == 0)
+            {
+            TBool en;
+            CSamplerPluginInterface::Str2Bool(aSetting.Right(aSetting.Length()-sepPos-1), en);
+            if(iSamplerAttributes->At(aIndex).iEnabled != en)
+                {
+                iSamplerAttributes->At(aIndex).iEnabled = en;
+                }
+            }
+        }
+    }
+
+TInt CBupPlugin::GetSamplerType()
+	{
+	return iSamplerType;
+	}
+
+TInt CBupPlugin::ResetAndActivateL(CProfilerSampleStream& aStream) 
+	{
+	LOGTEXT(_L("CBupPlugin::ResetAndActivate() - entry"));
+	TInt ret(KErrNone);
+	
+	// check if sampler enabled
+	if(iSamplerAttributes->At(0).iEnabled)
+	    {
+        // create first the listener instance
+        iButtonListener = CProfilerButtonListener::NewL(this);
+        
+        LOGTEXT(_L("CBupPlugin::ResetAndActivate() - listener created"));
+        
+        iStream = &aStream;
+        TInt length = this->CreateFirstSample();
+        iVersion[0] = (TUint8)length;
+        LOGSTRING2("CBupPlugin::ResetAndActivate() - AddSample, length %d",length);
+        ret = AddSample(iVersion, length+1, 0);
+        if(ret != KErrNone)
+            return ret;
+        
+        // activate button listener
+        ret = iButtonListener->StartL();
+
+        iEnabled = ETrue;
+        
+        LOGTEXT(_L("CBupPlugin::ResetAndActivate() - exit"));
+	    }
+	return ret;
+
+	}
+	
+TInt CBupPlugin::CreateFirstSample()
+	{
+	LOGTEXT(_L("CBupPlugin::CreateFirstSample - entry"));
+	this->iVersionDescriptor.Zero();
+	this->iVersionDescriptor.Append(_L8("Bappea_BUP_V"));
+	this->iVersionDescriptor.Append(PROFILER_BUP_SAMPLER_VERSION);
+	LOGTEXT(_L("CBupPlugin::CreateFirstSample - exit"));
+	return (TInt)(this->iVersionDescriptor.Length());
+	}
+
+TInt CBupPlugin::StopSampling() 
+	{
+	if(iButtonListener)
+		{
+		iButtonListener->Stop();
+		delete iButtonListener;	// delete listener after every trace
+		iButtonListener = NULL;
+		}
+	
+    // set disabled
+    iEnabled = EFalse;
+
+	return KErrNone;
+	}
+
+void CBupPlugin::FillThisStreamBuffer(TBapBuf* /*aBapBuf*/, TRequestStatus& /*aStatus*/)
+	{
+	}
+
+/*
+ * 
+ * Implementation of class CProfilerButtonListener
+ * 
+ */
+CProfilerButtonListener::CProfilerButtonListener(CBupPlugin* aSampler) 
+	{
+	LOGTEXT(_L("CProfilerButtonListener::CProfilerButtonListener() - konstuktori"));
+	this->iSampler = aSampler;
+	iSampleStartTime = 0;
+	LOGTEXT(_L("CProfilerButtonListener::CProfilerButtonListener() - konstuktori exit"));
+	}
+
+CProfilerButtonListener* CProfilerButtonListener::NewL(CBupPlugin* aSampler)
+	{
+	LOGTEXT(_L("CProfilerButtonListener::NewL() - entry"));
+	CProfilerButtonListener* self = new (ELeave) CProfilerButtonListener(aSampler);
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	CleanupStack::Pop();
+	LOGTEXT(_L("CProfilerButtonListener::NewL() - exit"));
+	return self;
+	}
+
+CProfilerButtonListener::~CProfilerButtonListener() 
+	{
+	LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener() - entry af"));
+
+	if(iMainWindow)
+		{
+		LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener(): flushing iWs"));
+		iWs.Flush();
+		LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener(): finishing"));
+		}
+	delete iMainWindow;
+	LOGTEXT(_L("CProfilerButtonListener::~CProfilerButtonListener() - exit"));
+	}
+	
+void CProfilerButtonListener::ConstructMainWindowL()
+	{
+    LOGTEXT(_L("CProfilerButtonListener::ConstructMainWindowL() - Entry"));
+
+    CWindow* window = new (ELeave) CWindow(this);
+    CleanupStack::PushL( window );
+	window->ConstructL(TRect(TPoint(0,0), TSize(0,0)));
+    delete iMainWindow;
+    iMainWindow = window;
+    CleanupStack::Pop( window );
+	
+    LOGTEXT(_L("CProfilerButtonListener::ConstructMainWindowL() - Exit"));
+	}
+
+void CProfilerButtonListener::HandleKeyEventL (TKeyEvent& /*aKeyEvent*/)
+    {
+    LOGTEXT(_L("CProfilerButtonListener::HandleKeyEventL() - Start"));
+    LOGTEXT(_L("CProfilerButtonListener::HandleKeyEventL() - End"));
+	}
+
+
+TInt CProfilerButtonListener::RunError(TInt aError)
+    {
+    // get rid of everything we allocated
+    // deactivate the anim dll before killing window, otherwise anim dll dies too early
+    iAnim->Deactivate();
+    iAnim->Close();
+
+    iAnimDll->Close();
+    
+    return aError;
+    }
+
+void CProfilerButtonListener::RunL() 
+	{	
+    // resubscribe before processing new value to prevent missing updates
+	IssueRequest();
+	
+	TInt c = 0;
+	if(RProperty::Get(KProfilerKeyEventPropertyCat, EProfilerKeyEventPropertySample, c) == KErrNone)
+		{
+		// do something with event
+		LOGSTRING2("CProfilerButtonListener::RunL() - event [%d] received",c);
+	
+		iSample[0] = c;
+		iSample[1] = c >> 8;
+		iSample[2] = c >> 16;
+		iSample[3] = c >> 24;
+		
+		// Space for GPP sample time		
+		TUint32 sampleTime = User::NTickCount() - iSampleStartTime; 
+		LOGSTRING2("CProfilerButtonListener::RunL() - sample time is %d",sampleTime);
+		
+		iSample[4] = sampleTime;
+		iSample[5] = sampleTime >> 8;
+		iSample[6] = sampleTime >> 16;
+		iSample[7] = sampleTime >> 24;
+		
+		iSampler->AddSample(iSample, 8, 0xb0);
+		}
+	}
+	
+TInt CProfilerButtonListener::StartL()
+	{
+	LOGTEXT(_L("CProfilerButtonListener::StartL() - Activate touch server dll"));
+	TInt err(KErrNone);
+	
+	// get the property value
+	TInt r = RProperty::Get(KGppPropertyCat, EGppPropertySyncSampleNumber, iSampleStartTime);
+	if(r != KErrNone)
+		{
+		LOGSTRING2("CProfilerButtonListener::StartL() - getting iSyncOffset failed, error %d", r);
+		}
+	
+	iAnimDll = new (ELeave) RAnimDll(iWs);
+	LOGTEXT(_L("CProfilerButtonListener::StartL() - #1"));
+	
+	TParse* fp = new (ELeave) TParse();
+	CleanupStack::PushL(fp);
+	fp->Set( KDllName, &KDC_SHARED_LIB_DIR , NULL );    
+	LOGSTRING2("CProfilerButtonListener::StartL() - touch event server: %S" , &(fp->FullName()));
+
+	err = iAnimDll->Load(fp->FullName());
+	// check if anim dll load failed
+	if(err != KErrNone)
+	    {
+        CleanupStack::PopAndDestroy(fp);
+	    // stop plugin if failed
+	    iAnimDll->Close();
+	    return KErrGeneral;
+	    }
+    CleanupStack::PopAndDestroy(fp);
+ 	LOGTEXT(_L("CProfilerButtonListener::StartL() - #2"));
+
+	iAnim = new (ELeave) RProfilerTouchEventAnim(*iAnimDll);
+ 	LOGTEXT(_L("CProfilerButtonListener::StartL() - #3"));
+	iAnim->ConstructL(iMainWindow->Window());
+	
+	// activate the animation dll for collecting touch and key events
+	iAnim->Activate();
+
+	// wait for a new sample
+	IssueRequest();
+	
+	// hide this window group from the app switcher
+	iMainWindow->Client()->Group().SetOrdinalPosition(-1);
+	iMainWindow->Client()->Group().EnableReceiptOfFocus(EFalse);
+	return KErrNone;
+	}
+
+TInt CProfilerButtonListener::Stop() 
+	{
+	LOGTEXT(_L("CProfilerButtonListener::Stop() - enter"));
+	// deactivate the anim dll before killing window, otherwise anim dll dies too early
+	iAnim->Deactivate();
+	iAnim->Close();
+
+	iAnimDll->Close();
+
+	Cancel();
+	LOGTEXT(_L("CProfilerButtonListener::Stop() - exit"));
+	return KErrNone;
+	}
+
+
+///////////////////////////////////////////////////////////////////////////////
+////////////////////////// CWindow implementation /////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+CWindow::CWindow(CWsClient* aClient)
+: iClient(aClient)
+	{
+    LOGTEXT(_L("CWindow::CWindow()"));
+	}
+
+void CWindow::ConstructL (const TRect& aRect, CWindow* aParent)
+	{
+	LOGTEXT(_L("CWindow::ConstructL(): Start"));
+
+	// If a parent window was specified, use it; if not, use the window group
+	// (aParent defaults to 0).
+	RWindowTreeNode* parent= aParent ? (RWindowTreeNode*) &(aParent->Window()) : &(iClient->iGroup);
+	iWindow=RWindow(iClient->iWs); // use app's session to window server
+	User::LeaveIfError(iWindow.Construct(*parent,(TUint32)this));
+	LOGSTRING2("CWindow::ConstructL(): Start - window handle is: 0x%08x", this);
+	iRect = aRect;
+	iWindow.SetExtent(iRect.iTl, iRect.Size()); // set extent relative to group coords
+	iWindow.Activate(); // window is now active
+	LOGTEXT(_L("CWindow::ConstructL(): End"));
+	}
+
+
+CWindow::~CWindow()
+	{
+    LOGTEXT(_L("CWindow::~CWindow(): Start"));
+	iWindow.Close(); // close our window
+    LOGTEXT(_L("CWindow::~CWindow(): End"));
+	}
+
+RWindow& CWindow::Window()
+	{
+    LOGTEXT(_L("CWindow::Window()"));
+	return iWindow;
+	}
+
+CWindowGc* CWindow::SystemGc()
+	{
+    LOGTEXT(_L("CWindow::SystemGc()"));
+	return iClient->iGc;
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////// CWsClient implementation ////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+CWsClient::CWsClient()
+: CActive(CActive::EPriorityStandard)
+	{
+    LOGTEXT(_L("CWsClient::CWsClient()"));
+	}
+
+void CWsClient::ConstructL()
+	{
+    LOGTEXT(_L("CWsClient::ConstructL() - Start"));
+    TInt r = RProperty::Define(EProfilerKeyEventPropertySample, RProperty::EInt, KAllowAllPolicy, KCapabilityNone);
+    if (r!=KErrAlreadyExists)
+        {
+        User::LeaveIfError(r);
+        }
+    
+	CActiveScheduler::Add(this);
+
+	// attach to 
+	User::LeaveIfError(iProperty.Attach(KProfilerKeyEventPropertyCat,EProfilerKeyEventPropertySample));
+    
+	// get a session going
+	User::LeaveIfError(iWs.Connect());
+
+	// construct screen device and graphics context
+	iScreen=new (ELeave) CWsScreenDevice(iWs); // make device for this session
+	User::LeaveIfError(iScreen->Construct( 0 )); // and complete its construction
+	User::LeaveIfError(iScreen->CreateContext(iGc)); // create graphics context
+
+	// construct our one and only window group
+	iGroup=RWindowGroup(iWs);
+	User::LeaveIfError(iGroup.Construct((TInt)this, EFalse)); // meaningless handle; enable focus
+	
+	// construct main window
+	ConstructMainWindowL();
+
+	LOGTEXT(_L("CWsClient::CWsClient() - End"));
+	}
+
+CWsClient::~CWsClient()
+	{
+    LOGTEXT(_L("CWsClient::~CWsClient() - Start"));
+    
+	// get rid of everything we allocated
+	delete iGc;
+	delete iScreen;
+	
+	iGroup.Close();
+	// finish with window server
+	iWs.Close();
+	
+    LOGTEXT(_L("CWsClient::~CWsClient() - Exit"));
+	}
+
+void CWsClient::Exit()
+	{
+    LOGTEXT(_L("CWsClient::Exit() - Start"));
+
+	// destroy window group
+	iGroup.Close();
+	// finish with window server
+    iProperty.Close();
+	iWs.Close();
+    LOGTEXT(_L("CWsClient::Exit() - Exit"));
+	}
+
+void CWsClient::IssueRequest()
+	{
+    LOGTEXT(_L("CWsClient::IssueRequest() - Start"));
+    iProperty.Subscribe( iStatus );
+    SetActive(); // so we're now active
+    LOGTEXT(_L("CWsClient::IssueRequest() - Exit"));
+	}
+
+void CWsClient::DoCancel()
+	{
+    LOGTEXT(_L("CWsClient::DoCancel() - Start"));
+	// clean up the sample property
+    iProperty.Cancel();
+    iProperty.Close();
+    LOGTEXT(_L("CWsClient::DoCancel() - Exit"));
+	}
+
+void CWsClient::ConstructMainWindowL()
+	{
+    LOGTEXT(_L("CWsClient::ConstructMainWindowL()"));
+	}
+