--- /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()"));
+ }
+