sysanadatacapture/piprofiler/piprofiler/engine/src/ProfilerEngine.cpp
changeset 1 3ff3fecb12fe
equal deleted inserted replaced
0:f0f2b8682603 1:3ff3fecb12fe
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32cons.h>
       
    20 #include <e32base.h>
       
    21 #include <f32file.h>
       
    22 #include <c32comm.h>
       
    23 #include <s32file.h>
       
    24 #include <pathinfo.h>
       
    25 #include <s32mem.h>
       
    26 #include <bautils.h>
       
    27 #include <sysutil.h>
       
    28 #include <piprofiler/ProfilerConfig.h>
       
    29 #include "ProfilerEngine.h"
       
    30 #include <piprofiler/ProfilerTraces.h>
       
    31 #include <piprofiler/EngineUIDs.h>
       
    32 
       
    33 // properties
       
    34 const TUid KEngineStatusPropertyCat={0x2001E5AD};
       
    35 enum TEnginePropertyKeys
       
    36 	{
       
    37 	EProfilerEngineStatus = 8,
       
    38 	EProfilerErrorStatus
       
    39 	};
       
    40 
       
    41 static _LIT_SECURITY_POLICY_PASS( KAllowAllPolicy );
       
    42 
       
    43 // CONSTANTS 
       
    44 const TInt KStreamBufferSize = 32768;
       
    45 const TInt KSavedLineCount = 64;
       
    46 const TInt KFileNameBufSize = 128;
       
    47 
       
    48 // LITERALS
       
    49 _LIT8(KGenericTraceOutput, "output_type");
       
    50 _LIT8(KGenericTraceFilePrefix, "file_prefix");
       
    51 _LIT8(KGenericTraceFileSaveDrive, "save_file_location");
       
    52 _LIT8(KEquals, "=");
       
    53 _LIT8(KNewLineSeparator, "\n");
       
    54 _LIT8(KProfilerVersionTag, "version");
       
    55 _LIT8(KEndMark, "[end]");
       
    56 _LIT8(KOutputToDebugOutput, "debug_output");
       
    57 
       
    58 /** 
       
    59  * 
       
    60  * The controller class used to provide the Profiler functions. 
       
    61  * This runs as a server in the engine thread
       
    62  * 
       
    63  */
       
    64 class CPServer : public CServer2, public MProfilerController
       
    65     {
       
    66 public:
       
    67     static MProfilerController*		NewL(TInt aPriority, MProfilerEngine& aEngine);
       
    68 
       
    69 private:
       
    70                         CPServer(TInt aPriority, MProfilerEngine& aEngine);
       
    71     void				Release();
       
    72     CSession2*			NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
       
    73     };
       
    74 
       
    75 // The session class used by the server controller
       
    76 class CPSession : public CSession2
       
    77     {
       
    78 private:
       
    79     inline const CPServer&	Server() const;
       
    80     void					ServiceL(const RMessage2& aMessage);
       
    81     };
       
    82 
       
    83 /*
       
    84  *
       
    85  *	CProfiler class implementation
       
    86  *
       
    87  */
       
    88 // --------------------------------------------------------------------------------------------
       
    89 CProfiler* CProfiler::NewLC(const TDesC& aSettingsFile)
       
    90     {
       
    91 	CProfiler* self = new(ELeave) CProfiler(aSettingsFile);
       
    92 	CleanupStack::PushL(self);
       
    93 	self->ConstructL();
       
    94 	return self;
       
    95     }
       
    96 
       
    97 // --------------------------------------------------------------------------------------------
       
    98 CProfiler::CProfiler(const TDesC& aSettingsFile) : 
       
    99     iSettingsFileLocation(aSettingsFile)
       
   100 	{
       
   101 	// define property for Profiler Engine status, UI may read it for control purposes
       
   102 	if ( RProperty::Define(KEngineStatusPropertyCat, 
       
   103 	        EProfilerEngineStatus, 
       
   104 	        RProperty::EInt, 
       
   105 	        KAllowAllPolicy, 
       
   106 	        KAllowAllPolicy, 
       
   107 	        0) != KErrAlreadyExists )
       
   108 	    {
       
   109 	    LOGTEXT(_L("CProfiler::CProfiler - status property already defined"));
       
   110 	    }
       
   111 
       
   112 	if ( RProperty::Define(KEngineStatusPropertyCat, 
       
   113 	        EProfilerErrorStatus, 
       
   114             RProperty::EInt, 
       
   115             KAllowAllPolicy, 
       
   116             KAllowAllPolicy, 
       
   117             0) != KErrAlreadyExists )
       
   118         {
       
   119         LOGTEXT(_L("CProfiler::CProfiler - status property already defined"));
       
   120         }
       
   121 
       
   122 	// attach to own property
       
   123 	iEngineStatus.Attach(KEngineStatusPropertyCat, EProfilerEngineStatus);
       
   124 	// set status idle
       
   125 	iEngineStatus.Set(KEngineStatusPropertyCat, EProfilerEngineStatus, RProfiler::EIdle);
       
   126 	
       
   127     // attach to own property
       
   128     iUpdateStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus);
       
   129     // set status idle
       
   130     iUpdateStatus.Set(KEngineStatusPropertyCat, EProfilerErrorStatus, EFalse);
       
   131 	}
       
   132 
       
   133 // --------------------------------------------------------------------------------------------
       
   134 CProfiler::~CProfiler()
       
   135     {
       
   136 	LOGTEXT(_L("CProfiler::~CProfiler - Enter"));
       
   137 
       
   138 	// delete error checker
       
   139     if(iErrorChecker)
       
   140         {
       
   141         iErrorChecker->Cancel();
       
   142         delete iErrorChecker;
       
   143         iErrorChecker = NULL;
       
   144         }
       
   145 	
       
   146 	// delete settings array
       
   147 	if(iDefaultSamplerAttributesArray)
       
   148 	    {
       
   149 	    iDefaultSamplerAttributesArray->Reset();
       
   150 	    delete iDefaultSamplerAttributesArray;
       
   151 	    iDefaultSamplerAttributesArray = NULL;
       
   152 	    }
       
   153 
       
   154     // delete settings file raw line array
       
   155     if(iSavedLineArray)
       
   156         {
       
   157         iSavedLineArray->Reset();
       
   158         delete iSavedLineArray;
       
   159         iSavedLineArray = NULL;
       
   160         }
       
   161 		
       
   162 	// delete sampler controller, cleans up the sampler plugin instances
       
   163 	if(iSamplerHandler)
       
   164 		{
       
   165 		delete iSamplerHandler;
       
   166 		iSamplerHandler = NULL;
       
   167 		}
       
   168 	// delete writer controller, cleans up the writer plugin instances
       
   169 	if(iWriterHandler)
       
   170 		{
       
   171 		delete iWriterHandler;
       
   172 		iWriterHandler = NULL;
       
   173 		}
       
   174 
       
   175     // delete user side sampler stream 
       
   176 	if(iUserStream)
       
   177 		{
       
   178 		delete iUserStream;
       
   179 		iUserStream = NULL;
       
   180 		}
       
   181 
       
   182 	// close engine status property
       
   183 	iEngineStatus.Close();
       
   184 	if (RProperty::Delete(KEngineStatusPropertyCat, EProfilerEngineStatus) != KErrNotFound)
       
   185 	    {
       
   186 	    LOGTEXT(_L("CProfiler::~CProfiler - cannot close status property"));
       
   187 	    }
       
   188     // close engine update property
       
   189     iUpdateStatus.Close();
       
   190     if (RProperty::Delete(KEngineStatusPropertyCat, EProfilerErrorStatus) != KErrNotFound)
       
   191         {
       
   192         LOGTEXT(_L("CProfiler::~CProfiler - cannot close update property"));
       
   193         }
       
   194     
       
   195     // close server process
       
   196     if (iServer)
       
   197         {
       
   198         LOGTEXT(_L("CProfiler::~CProfiler - Releasing server"));
       
   199         iServer->Release();
       
   200         }
       
   201     
       
   202 	LOGTEXT(_L("CProfiler::~CProfiler - Finished"));
       
   203     }
       
   204 
       
   205 // --------------------------------------------------------------------------------------------
       
   206 void CProfiler::ConstructL()
       
   207     {
       
   208 	LOGTEXT(_L("CProfiler::ConstructL - Enter"));
       
   209 	TInt err(0);
       
   210 
       
   211     // create new sampler stream instance
       
   212     iUserStream = CProfilerSampleStream::NewL(KStreamBufferSize);
       
   213     if(!iUserStream)
       
   214         {
       
   215         LOGTEXT(_L("Profiler engine cannot reserve memory"));
       
   216         User::Leave(KErrCancel);   // operation cancelled
       
   217         }
       
   218 	
       
   219     // engine status checker
       
   220     iErrorChecker = CProfilerErrorChecker::NewL();
       
   221     iErrorChecker->SetObserver(this);
       
   222 
       
   223 	// create and initiate plug-in controller instances
       
   224     iSamplerHandler = CSamplerController::NewL(*iUserStream);
       
   225     iWriterHandler = CWriterController::NewL(*iUserStream);
       
   226     
       
   227     iWriterHandler->InitialiseWriterListL();
       
   228     
       
   229     // set engine as an observer to sampler controller to get the notification of plugin load has ended
       
   230     iSamplerHandler->SetObserver(this);
       
   231     
       
   232     // default settings from sampler plugins, maximum 20 sampler plugins
       
   233     iDefaultSamplerAttributesArray = new(ELeave) CArrayFixFlat<TSamplerAttributes>(20); 
       
   234     
       
   235     // set profiler status to initializing
       
   236     iState = RProfiler::EInitializing;
       
   237 	iEngineStatus.Set(RProfiler::EInitializing);
       
   238 	
       
   239 	// set default general settings, will be overdriven if changed in settings file
       
   240 	iGeneralAttributes.iTraceOutput.Copy(KDefaultTraceOutput);
       
   241 	iGeneralAttributes.iTraceFilePrefix.Copy(KDefaultTraceFilePrefix);
       
   242 	iGeneralAttributes.iSaveFileDrive.Copy(KDefaultTraceFileSaveDrive);
       
   243 	
       
   244 	RThread me;
       
   245 	
       
   246 	me.SetPriority(EPriorityRealTime);
       
   247 
       
   248 	err = KErrGeneral;
       
   249 	TInt count = 0;
       
   250 
       
   251 	while(err != KErrNone && count < 30)
       
   252 	    {
       
   253 		err = User::RenameThread(KProfilerName);
       
   254 		if(err != KErrNone)
       
   255 		    {
       
   256 			User::Leave(err);
       
   257 		    }
       
   258 		else break;
       
   259 	    }
       
   260 
       
   261 	if(err != KErrNone) 
       
   262 	    {
       
   263 		User::Leave(err);
       
   264 	    }
       
   265 
       
   266 	// set settings file loading preferences
       
   267 	iSettingsFileLoaded = EFalse;
       
   268 
       
   269 	// change status property to idle since initialization successfull
       
   270 	iState = RProfiler::EIdle;
       
   271 	if( iEngineStatus.Set((TInt)RProfiler::EIdle) != KErrNone )
       
   272 	    {
       
   273 	    LOGTEXT(_L("CProfiler::ConstructL - engine status property change failed"));
       
   274 	    }
       
   275 
       
   276     if( iUpdateStatus.Set(EFalse) != KErrNone )
       
   277         {
       
   278         LOGTEXT(_L("CProfiler::ConstructL - engine status property change failed"));
       
   279         }
       
   280 
       
   281 	// create a server instance for clients to communicate with 
       
   282 	iServer = CPServer::NewL(10,*this);
       
   283 	
       
   284 	// close the handle 
       
   285 	me.Close();
       
   286 	
       
   287 	LOGTEXT(_L("CProfiler::ConstructL - Exit"));
       
   288 	
       
   289     }
       
   290 
       
   291 CProfilerSampleStream* CProfiler::GetSamplerStream()
       
   292     {
       
   293     return iUserStream;
       
   294     }
       
   295 
       
   296 void CProfiler::HandleSamplerControllerReadyL()
       
   297     {
       
   298     // load settings
       
   299     // check if settings file already loaded
       
   300     if(!iSettingsFileLoaded)
       
   301         {
       
   302         // load default settings file
       
   303         LoadSettingsL();
       
   304 
       
   305         iSettingsFileLoaded = ETrue;
       
   306         }
       
   307     
       
   308     // notify engine's launcher(UI or PIProfilerLauncher) to continue launch
       
   309     RProcess::Rendezvous(KErrNone); 
       
   310     }
       
   311 
       
   312 void CProfiler::NotifyRequesterForSettingsUpdate()
       
   313     {
       
   314     // set update status P&S property true => update needed on UI side
       
   315     iUpdateStatus.Set(ETrue);
       
   316     }
       
   317 
       
   318 void CProfiler::HandleProfilerErrorChangeL(TInt aError)
       
   319     {
       
   320     LOGSTRING2("CProfiler::HandleProfilerErrorChangeL() - error received, %d", aError);
       
   321     
       
   322     // check if profiler running
       
   323     if(iState == RProfiler::ERunning)
       
   324         {
       
   325         // stop profiler if error occurred during the trace
       
   326         iEngineStatus.Set(aError);
       
   327         
       
   328         // stop samplers, NOTE! Writer plugins not stopped since 
       
   329         iSamplerHandler->StopSamplerPlugins();
       
   330 
       
   331         // stop debug output plugin and write the rest of the trace data to output
       
   332         if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)   
       
   333             {
       
   334             // write the rest of trace data only if debug output selected
       
   335             iWriterHandler->StopSelectedPlugin();
       
   336             }
       
   337         LOGSTRING2("CProfiler::HandleProfilerErrorChangeL - sampling stopped, going to state %d", RProfiler::EIdle);
       
   338         }
       
   339     }
       
   340 
       
   341 // ----------------------------------------------------------------------------
       
   342 // Gets a value from settings file for certain attribute.
       
   343 // ----------------------------------------------------------------------------
       
   344 void CProfiler::DoGetValueFromSettingsArray(CDesC8ArrayFlat* aLineArray, const TDesC8& aAttribute, TDes8& aValue)
       
   345     {
       
   346     LOGTEXT(_L("CProfiler::DoGetValueFromSettingsFile()"));
       
   347     _LIT8(KSettingItemSeparator, "=");
       
   348     
       
   349     // read a line of given array
       
   350     for (TInt i=0; i<aLineArray->MdcaCount(); i++)
       
   351         {
       
   352         // check if this line has a separator
       
   353         TInt sepPos = aLineArray->MdcaPoint(i).Find(KSettingItemSeparator);
       
   354         if (sepPos > 0)
       
   355             {
       
   356             // check that the element matches
       
   357             if (aLineArray->MdcaPoint(i).Left(sepPos).CompareF(aAttribute) == 0)
       
   358                 {
       
   359                 // get the value
       
   360                 aValue.Copy(aLineArray->MdcaPoint(i).Right(aLineArray->MdcaPoint(i).Length()-sepPos-1));
       
   361                 break;
       
   362                 }
       
   363             }
       
   364         }
       
   365     }
       
   366 
       
   367 // --------------------------------------------------------------------------------------------
       
   368 TInt CProfiler::GetSamplerAttributesL(const RMessage2& aMessage)
       
   369     {
       
   370     TInt err(KErrNone);
       
   371     TInt pos(0);
       
   372 
       
   373     // get sampler count
       
   374     TInt count(iDefaultSamplerAttributesArray->Count());
       
   375 
       
   376     // write each of the default sampler plugin setting attributes over client-server session 
       
   377     for (TInt i(0); i<count; ++i)
       
   378        {
       
   379        TSamplerAttributes attr = iDefaultSamplerAttributesArray->At(i);
       
   380        TPckgC<TSamplerAttributes> attrPckg(attr);
       
   381        
       
   382        // write a TSamplerAttributes container at a time
       
   383        aMessage.WriteL(0, attrPckg, pos);
       
   384        pos += attrPckg.Length();
       
   385        }
       
   386 
       
   387     aMessage.Complete(err);
       
   388     return err;
       
   389     }
       
   390 
       
   391 // --------------------------------------------------------------------------------------------
       
   392 TInt CProfiler::SetSamplerAttributesL(const RMessage2& aMessage)
       
   393     {
       
   394     TSamplerAttributes attr;
       
   395     TPckg<TSamplerAttributes> inAttr(attr);
       
   396     
       
   397     TInt err = aMessage.Read(0, inAttr, 0);    
       
   398     
       
   399     // apply the changes directly to a plugin
       
   400     iSamplerHandler->SetSamplerSettingsL(attr.iUid, attr);
       
   401     
       
   402     aMessage.Complete(err);
       
   403     return err;
       
   404     }
       
   405 
       
   406 // --------------------------------------------------------------------------------------------
       
   407 TInt CProfiler::GetGeneralAttributesL(const RMessage2& aMessage)
       
   408     {
       
   409     TPckgBuf<TGeneralAttributes> generalSettings( iGeneralAttributes );
       
   410     
       
   411     // write general attributes over client-server session
       
   412     TInt err = aMessage.Write(0, generalSettings);
       
   413     
       
   414     aMessage.Complete(err);
       
   415     return err;
       
   416     }
       
   417 
       
   418 // --------------------------------------------------------------------------------------------
       
   419 TInt CProfiler::SetGeneralAttributesL(const RMessage2& aMessage)
       
   420     {
       
   421     // read the general settings from message
       
   422     TGeneralAttributes attr;
       
   423     TPckg<TGeneralAttributes> inPckg(attr);
       
   424     TInt err = aMessage.Read(0, inPckg, 0);
       
   425     
       
   426     // copy to the general attributes
       
   427     iGeneralAttributes.iSaveFileDrive.Copy(attr.iSaveFileDrive);
       
   428     iGeneralAttributes.iTraceFilePrefix.Copy(attr.iTraceFilePrefix);
       
   429     iGeneralAttributes.iTraceOutput.Copy(attr.iTraceOutput);
       
   430     
       
   431     aMessage.Complete(err);
       
   432     return err;
       
   433     }
       
   434 
       
   435 TInt CProfiler::GetSamplerAttributeCountL(const RMessage2& aMessage)
       
   436     {
       
   437     // get the plugin array count and wrap it to TPckgBuf<>
       
   438     TPckgBuf<TInt> attributeCount(iDefaultSamplerAttributesArray->Count());
       
   439     
       
   440     // write general attributes over client-server session
       
   441     TInt err = aMessage.Write(0, attributeCount);
       
   442     
       
   443     aMessage.Complete(err);
       
   444     return err;
       
   445     }
       
   446 
       
   447 TInt CProfiler::RefreshStatus(const RMessage2& aMessage)
       
   448     {
       
   449     TInt err(KErrNone);
       
   450     
       
   451     // update profiler status for requester
       
   452     iEngineStatus.Set(iState);
       
   453     
       
   454     aMessage.Complete(err);
       
   455     return err;
       
   456     }
       
   457 
       
   458 // --------------------------------------------------------------------------------------------
       
   459 TInt CProfiler::LoadSettingsL(/*const TDesC& configFile*/)
       
   460     {
       
   461 	RFs fileServer;
       
   462 	RFile file;
       
   463 	TInt err(KErrNone);
       
   464     
       
   465 	// connect to file server 
       
   466 	err = fileServer.Connect();
       
   467 	
       
   468 	// check if file server can be connected
       
   469 	if (err != KErrNone)
       
   470 	    {
       
   471 		// file server couldn't be connected
       
   472 		return KErrGeneral;
       
   473 	    }
       
   474 
       
   475 	// check if settings file location length reasonable
       
   476 	if ( iSettingsFileLocation.CompareF(KNullDesC) == 0 )
       
   477 	    {
       
   478 		// open the file with the default path and name
       
   479 		TBuf<256> pathAndName;
       
   480 		pathAndName.Append(PathInfo::PhoneMemoryRootPath());
       
   481 		pathAndName.Append(KProfilerSettingsFileName);
       
   482 		iSettingsFileLocation.Copy(pathAndName);
       
   483 		LOGTEXT(_L("CProfiler::LoadSettings - Opening settings file with name (with the default path)"));
       
   484 		LOGTEXT(pathAndName);
       
   485 	    }
       
   486 
       
   487     // open the file with the given path and name
       
   488     err = file.Open(fileServer,iSettingsFileLocation,EFileRead);
       
   489 
       
   490 	
       
   491 	// check if RFile::Open() returned error
       
   492 	if (err != KErrNone)
       
   493 	    {
       
   494 		// file couldn't be opened
       
   495 		LOGTEXT(_L("CProfiler::LoadSettings - Failed to open settings, using default"));
       
   496 
       
   497 		// check if settings already loaded
       
   498 		if(iDefaultSamplerAttributesArray->Count() > 0)
       
   499 		    {
       
   500 		    // reset default settings array
       
   501 		    iDefaultSamplerAttributesArray->Reset();
       
   502 		    }
       
   503 		
       
   504 		// load default settings, instead of settings file ones
       
   505 		iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
       
   506 		
       
   507 		fileServer.Close();
       
   508 		return KErrNone;
       
   509 	    }
       
   510 	
       
   511 	// initialize iSavedLineArray, initial settings file lines 64
       
   512 	if(iSavedLineArray)
       
   513 	    {
       
   514         iSavedLineArray->Reset();
       
   515 	    }
       
   516 	else
       
   517 	    {
       
   518         iSavedLineArray = new (ELeave) CDesC8ArrayFlat(KSavedLineCount);
       
   519 	    }
       
   520 	
       
   521 	iSavedLinesCount = KSavedLineCount;
       
   522 	
       
   523     // get size of the file
       
   524     TInt fileSize(0);
       
   525     err = file.Size(fileSize);
       
   526     // check if an error occurred reading the file size
       
   527     if(err != KErrNone)
       
   528         {
       
   529         return KErrGeneral; // could not find the size
       
   530         }
       
   531         
       
   532     // sanity check for the file size
       
   533     if (fileSize < 3 || fileSize > 20000)
       
   534         {
       
   535         fileSize = KSettingsFileSize;
       
   536         return KErrNotSupported;
       
   537         }
       
   538     
       
   539 	// read the contents of the file to buffer. 
       
   540 	iSettingsBuffer.Zero();
       
   541 	file.Read(iSettingsBuffer, fileSize);
       
   542 	file.Close();
       
   543 	fileServer.Close();
       
   544 	LOGSTRING2("CProfiler::LoadSettings: read %d bytes",iSettingsBuffer.Length());
       
   545 
       
   546 	// append end mark "[end]"
       
   547     iSettingsBuffer.Append(KEndMark);
       
   548 	// force an ending newline
       
   549 	iSettingsBuffer.Append('\n');
       
   550 
       
   551 	// next fill the saved settings array (CDesC8ArrayFlat) for further comparison with changes and default values
       
   552     TBuf8<384> tmpBuf;
       
   553     TInt lineCount(0);
       
   554     TBool commentFound(EFalse);
       
   555     for (TInt i(0); i<iSettingsBuffer.Length(); i++)  // loop all chars
       
   556         {
       
   557         // if new line char found, create a new text line
       
   558         if (iSettingsBuffer[i]=='\r' || iSettingsBuffer[i]=='\n')
       
   559             {
       
   560             // check if collected string has reasonable length
       
   561             if (tmpBuf.Length() > 0)
       
   562                 {
       
   563                 // remove extra spaces
       
   564                 tmpBuf.TrimAll();
       
   565                 // check if the size of the array too small
       
   566                 if(lineCount >= iSavedLinesCount)
       
   567                     {
       
   568                     iSavedLineArray->ExpandL(20);   // expand by 20 lines
       
   569                     iSavedLinesCount += 20;
       
   570                     }
       
   571                 iSavedLineArray->AppendL(tmpBuf);
       
   572                 tmpBuf.Copy(KNullDesC8);
       
   573                 lineCount++;
       
   574                 }
       
   575             commentFound = EFalse;
       
   576             }
       
   577         // check if comment mark ';' is found on the line, skip the rest of the line
       
   578         else if(iSettingsBuffer[i]==';')
       
   579             {
       
   580             commentFound = ETrue;
       
   581             }
       
   582         // otherwise append a char to the temp line buffer if it is a wanted ASCII char
       
   583         else if (iSettingsBuffer[i]>=32 && iSettingsBuffer[i]<=127 && !commentFound)
       
   584             {
       
   585             tmpBuf.Append(iSettingsBuffer[i]);
       
   586             }
       
   587         }
       
   588     
       
   589     // empty tmpBuf
       
   590     tmpBuf.Copy(KNullDesC8);
       
   591     // check settings file version
       
   592     DoGetValueFromSettingsArray(iSavedLineArray, KProfilerVersionTag, tmpBuf); 
       
   593 
       
   594     TBuf8<32> version;
       
   595     version.Copy(PROFILER_VERSION_SHORT);
       
   596     
       
   597     // check if settings file version is 
       
   598     if(tmpBuf.CompareF(version) >= 0)
       
   599         {
       
   600         // update general attributes
       
   601         UpdateSavedGeneralAttributes(iSavedLineArray);
       
   602         
       
   603         // update settings to sampler plugins and save the attributes to default array
       
   604         iSamplerHandler->UpdateSavedSamplerAttributesL(iSavedLineArray, iDefaultSamplerAttributesArray);
       
   605         }
       
   606     else
       
   607         {
       
   608         // check if settings already loaded
       
   609         if(iDefaultSamplerAttributesArray)
       
   610             {
       
   611             // reset default settings array
       
   612             iDefaultSamplerAttributesArray->Reset();
       
   613             }
       
   614         // get the default settings if settings file version too old
       
   615         iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
       
   616         }
       
   617     
       
   618 	return err; 
       
   619     }
       
   620 
       
   621 // --------------------------------------------------------------------------------------------
       
   622 void CProfiler::UpdateSavedGeneralAttributes(CDesC8ArrayFlat* aSavedAttributes)
       
   623     {
       
   624     // get saved general settings
       
   625     DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceOutput, iGeneralAttributes.iTraceOutput);
       
   626     DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceFilePrefix, iGeneralAttributes.iTraceFilePrefix);
       
   627     DoGetValueFromSettingsArray(aSavedAttributes, KGenericTraceFileSaveDrive, iGeneralAttributes.iSaveFileDrive);
       
   628 
       
   629     }
       
   630 
       
   631 TBool CProfiler::CheckLocationSanity(RFs& fs, const TDesC8& aLocation)
       
   632     {
       
   633     TBool ret(EFalse);
       
   634 
       
   635     TBuf<32> drive;
       
   636     
       
   637     CnvUtfConverter::ConvertToUnicodeFromUtf8(drive, aLocation);
       
   638     
       
   639     // check that aLocation contains some of reasonable drives 
       
   640     if(aLocation.Find(_L8("C:\\")) != KErrNotFound)
       
   641         {
       
   642         if(BaflUtils::CheckFolder(fs, drive) == KErrNone && 
       
   643             !SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, EDriveC))
       
   644             ret = ETrue;
       
   645         }
       
   646     else if(aLocation.Find(_L8("D:\\")) != KErrNotFound) 
       
   647         {
       
   648         if(BaflUtils::CheckFolder(fs, drive) == KErrNone && 
       
   649             !SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, EDriveD))
       
   650             ret = ETrue;
       
   651         }
       
   652     else if(aLocation.Find(_L8("E:\\")) != KErrNotFound) 
       
   653         {
       
   654         if(BaflUtils::CheckFolder(fs, drive) == KErrNone && 
       
   655             !SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, EDriveE))
       
   656             ret = ETrue;
       
   657         }
       
   658     else if(aLocation.Find(_L8("F:\\")) != KErrNotFound) 
       
   659         {
       
   660         if(BaflUtils::CheckFolder(fs, drive) == KErrNone && 
       
   661             !SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, EDriveF))
       
   662             ret = ETrue;
       
   663         }
       
   664     else if(aLocation.Find(_L8("G:\\")) != KErrNotFound) 
       
   665         {
       
   666         if(BaflUtils::CheckFolder(fs, drive) == KErrNone && 
       
   667             !SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, EDriveG))
       
   668             ret = ETrue;
       
   669         }
       
   670     else if(aLocation.Find(_L8("H:\\")) != KErrNotFound ) 
       
   671         {
       
   672         if(BaflUtils::CheckFolder(fs, drive) == KErrNone && 
       
   673             !SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, EDriveH))
       
   674             ret = ETrue;
       
   675         }
       
   676     else if(aLocation.Find(_L8("I:\\")) != KErrNotFound) 
       
   677         {
       
   678         if(BaflUtils::CheckFolder(fs, drive) == KErrNone && 
       
   679                 !SysUtil::DiskSpaceBelowCriticalLevelL(&fs, 0, EDriveI))
       
   680             ret = ETrue;
       
   681         }
       
   682     else
       
   683         {
       
   684         // otherwise return false
       
   685         ret = EFalse;
       
   686         }
       
   687     
       
   688     return ret;
       
   689     }
       
   690 
       
   691 TInt CProfiler::HandleGeneralSettingsChange()
       
   692     {
       
   693     // local literals
       
   694     _LIT8(KBackSlash, "\\");
       
   695     _LIT8(KTraceFileExtension, ".dat");
       
   696     
       
   697     TBuf8<KFileNameBufSize> fileNameBuf;
       
   698     TBuf8<10> number;
       
   699     TInt result(0);
       
   700     TInt index(1);
       
   701     TInt hashLocation(0);
       
   702     TParse parse;
       
   703 
       
   704     // check if plugin writer changed
       
   705     if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)
       
   706         {
       
   707         iWriterHandler->SetPluginActive( KDebOutWriterPluginUid, EWriterPluginEnabled );
       
   708         }
       
   709     else
       
   710         {
       
   711         RFs fileServer;
       
   712         RFile file;
       
   713         
       
   714         // connect to the file server
       
   715         result = fileServer.Connect();
       
   716         if(result == KErrNone)
       
   717             {
       
   718             // disk writer plugin will be activated
       
   719             iWriterHandler->SetPluginActive( KDiskWriterPluginUid, EWriterPluginEnabled );
       
   720             
       
   721             // fix the trace data file location as well
       
   722             iTotalPrefix.Zero();
       
   723             iTotalPrefix.Append(iGeneralAttributes.iSaveFileDrive);
       
   724             
       
   725             // check that trace file location sane
       
   726             if(!CProfiler::CheckLocationSanity(fileServer, iTotalPrefix))
       
   727                 {
       
   728 //                // empty location data
       
   729 //                iTotalPrefix.Zero();
       
   730 //                // use default location instead
       
   731 //                iTotalPrefix.Append(KProfilerDefaultDrive);
       
   732                 fileServer.Close();
       
   733                 return KErrPathNotFound;
       
   734                 }
       
   735             
       
   736             // remove extra spaces
       
   737             iTotalPrefix.TrimAll();
       
   738             
       
   739             // check if trace data location directory => string ends with '\' 
       
   740             if(iTotalPrefix.LocateReverse('\\') != iTotalPrefix.Length()-1 && 
       
   741                     iTotalPrefix.LocateReverse('/') != iTotalPrefix.Length()-1)
       
   742                 {
       
   743                 // append backslash to end
       
   744                 iTotalPrefix.Append(KBackSlash);
       
   745                 }
       
   746             
       
   747             // append trace file name prefix e.g. PIProfiler_#
       
   748             iTotalPrefix.Append(iGeneralAttributes.iTraceFilePrefix);
       
   749     
       
   750             // locate '#' mark for finding the next free trace file name, e.g. E:\data\PIProfiler_4.dat
       
   751             hashLocation = iTotalPrefix.Locate('#');
       
   752             if( hashLocation == KErrNotFound )
       
   753                 {
       
   754                 // append simply at the end of the trace file prefix, no need to inform user
       
   755                 iTotalPrefix.Append('#');
       
   756                 // get new hash mark location
       
   757                 hashLocation = iTotalPrefix.Locate('#');
       
   758                 }
       
   759     
       
   760             // add the file extension
       
   761             iTotalPrefix.Append(KTraceFileExtension);
       
   762 
       
   763             // search for files with different indices
       
   764             // until a free filename is found
       
   765             while(result != KErrNotFound)
       
   766                 {
       
   767                 fileNameBuf.Zero();
       
   768                 // start with the original prefix
       
   769                 fileNameBuf.Append(iTotalPrefix);
       
   770                 // convert the number to a descriptor
       
   771                 number.Num(index);
       
   772                 // replace the hashmark with the real number
       
   773                 fileNameBuf.Replace(hashLocation,1,number);
       
   774                 
       
   775                 // make a copy to the iFileNameStream descriptor
       
   776                 iFileNameStream.Zero();
       
   777                 CnvUtfConverter::ConvertToUnicodeFromUtf8(iFileNameStream, fileNameBuf);
       
   778                 
       
   779                 LOGSTRING2("CProfiler::HandleGeneralSettingsChange() - trying to open files %S ",&iFileNameStream);
       
   780 
       
   781                 if((result = parse.Set(iFileNameStream, NULL, NULL)) != KErrNone)
       
   782                     {
       
   783                     // break loop if fails, problems in file name => change to log into debug output
       
   784                     break;
       
   785                     }
       
   786                 
       
   787                 // create directory for trace files if not exists
       
   788                 result = fileServer.MkDirAll(parse.FullName());
       
   789 
       
   790                 // check that file server responded with KErrNone or KErrAlreadyExists
       
   791                 if( result != KErrNone && result != KErrAlreadyExists)
       
   792                     {
       
   793                     // if some other result, e.g. memory full => break
       
   794                     break;
       
   795                     }
       
   796 
       
   797                 // attempt opening the file
       
   798                 result = file.Open(fileServer,parse.FullName(),EFileShareReadersOnly);
       
   799                 if(result != KErrNotFound)
       
   800                     {
       
   801                     if( result != KErrNotReady && 
       
   802                         result != KErrServerBusy ) 
       
   803                         {
       
   804                         // close the file if it could be opened
       
   805                         LOGSTRING2("Found STREAM file with index %d",index);
       
   806                         index++;
       
   807                         }
       
   808                     else 
       
   809                         {
       
   810                         // in boot measurements the file system might not be ready yet.
       
   811                         LOGSTRING2("Problem in opening STREAM file %d",index);
       
   812                         }
       
   813                     file.Close();
       
   814                     }
       
   815                 } // while
       
   816             }
       
   817         else
       
   818             {
       
   819             // return error code
       
   820             return result;
       
   821             }
       
   822         
       
   823         TUint32 id(iWriterHandler->GetActiveWriter()->GetWriterType());
       
   824         
       
   825         // check if a file name is one that does not exist and selected plugin is disk writer
       
   826         if(result == KErrNotFound && id == KDiskWriterPluginUid.iUid)
       
   827             {
       
   828             // write right trace data file name to disk writer plugin
       
   829             iWriterHandler->SetPluginSettings( KDiskWriterPluginUid, iFileNameStream );
       
   830             }
       
   831         else
       
   832             {
       
   833             // return error if could not create trace log file
       
   834             return result;
       
   835             }
       
   836         // close file server
       
   837         fileServer.Close();
       
   838         }   // if output == KOutputToDebugOutput
       
   839     return KErrNone;
       
   840     }
       
   841 
       
   842 // --------------------------------------------------------------------------------------------
       
   843 void CProfiler::SaveSettingsL()
       
   844     {
       
   845     LOGTEXT(_L("CProfiler::SaveSettings()"));
       
   846     
       
   847     // local literal
       
   848     _LIT(KGeneralHeader, "[general]");
       
   849     _LIT(KVersionHeader, "version");
       
   850     _LIT8(KPIProfilerSettingsHeader, "; PI Profiler Settings File");
       
   851     _LIT8(KGeneralSettingsHeader, "; general settings");
       
   852     _LIT8(KOutputFileDescription,"; \"output_type=file_system\" writes *.dat file to external memory");
       
   853     _LIT8(KOutputDebugDescription,"; \"output_type=debug_output\" writes *.dat file to debug port");
       
   854     _LIT8(KOutputFilePrefixDescription,"; if writing to file, prefix of the *.dat file\r\n; first '#' in the prefix is replaced with an integer");
       
   855     _LIT8(KOutputSaveDriveDescription,"; if writing to file, the location to store the *.dat file");
       
   856     
       
   857     RFs fs;
       
   858     RFile settingsFile;
       
   859     TInt err(KErrNone);
       
   860     TBuf8<384> line;
       
   861     
       
   862     // connect to file server
       
   863     err = fs.Connect();
       
   864     if( err != KErrNone )
       
   865         {
       
   866         // failed to write settings to settings file
       
   867         return;
       
   868         }
       
   869     
       
   870     // create and set the private path
       
   871     fs.CreatePrivatePath(EDriveC);
       
   872     fs.SetSessionToPrivate(EDriveC);
       
   873   
       
   874     // create the new settings file
       
   875     err = settingsFile.Replace(fs, iSettingsFileLocation, EFileWrite);
       
   876     if(err != KErrNone)
       
   877         return;
       
   878     
       
   879     CleanupClosePushL(settingsFile);  
       
   880 
       
   881     // write the header
       
   882     line.Copy(KPIProfilerSettingsHeader);
       
   883     line.Append(KNewLineSeparator);
       
   884     line.Append(KNewLineSeparator);
       
   885     settingsFile.Write(line);
       
   886     
       
   887     // write the header
       
   888     line.Copy(KGeneralSettingsHeader);
       
   889     line.Append(KNewLineSeparator);
       
   890     settingsFile.Write(line);
       
   891 
       
   892     // write all generic settings
       
   893     line.Copy(KGeneralHeader);
       
   894     line.Append(KNewLineSeparator);
       
   895     settingsFile.Write(line);
       
   896 
       
   897     // write version info
       
   898     line.Copy(KVersionHeader);
       
   899     line.Append(KEquals);
       
   900     line.Append(PROFILER_VERSION_SHORT);
       
   901     line.Append(KNewLineSeparator);
       
   902     settingsFile.Write(line);
       
   903 
       
   904     // output explanation
       
   905     line.Copy(KOutputFileDescription);
       
   906     line.Append(KNewLineSeparator);
       
   907     line.Append(KOutputDebugDescription);
       
   908     line.Append(KNewLineSeparator);
       
   909     settingsFile.Write(line);
       
   910     
       
   911     // write trace output
       
   912     line.Copy(KGenericTraceOutput);
       
   913     line.Append(KEquals);
       
   914     line.Append(iGeneralAttributes.iTraceOutput);
       
   915     line.Append(KNewLineSeparator);
       
   916     settingsFile.Write(line);
       
   917     
       
   918     // file prefix explanation
       
   919     line.Copy(KOutputFilePrefixDescription);
       
   920     line.Append(KNewLineSeparator);
       
   921     settingsFile.Write(line);
       
   922 
       
   923     // write trace file prefix
       
   924     line.Copy(KGenericTraceFilePrefix);
       
   925     line.Append(KEquals);
       
   926     line.Append(iGeneralAttributes.iTraceFilePrefix);
       
   927     line.Append(KNewLineSeparator);
       
   928     settingsFile.Write(line);
       
   929     
       
   930     // file prefix explanation
       
   931     line.Copy(KOutputSaveDriveDescription);
       
   932     line.Append(KNewLineSeparator);
       
   933     settingsFile.Write(line);
       
   934 
       
   935     // write trace file location
       
   936     line.Copy(KGenericTraceFileSaveDrive);
       
   937     line.Append(KEquals);
       
   938     line.Append(iGeneralAttributes.iSaveFileDrive);
       
   939     line.Append(KNewLineSeparator);
       
   940     settingsFile.Write(line);
       
   941     
       
   942     // reset the default attributes array
       
   943     iDefaultSamplerAttributesArray->Reset();
       
   944     
       
   945     // update the latest changes from plugins
       
   946     iSamplerHandler->GetSamplerAttributesL(iDefaultSamplerAttributesArray);
       
   947     
       
   948     // call CSamplerController to write all sampler settings
       
   949     iSamplerHandler->ComposeAttributesToSettingsFileFormat(settingsFile, iDefaultSamplerAttributesArray);
       
   950     
       
   951     CleanupStack::PopAndDestroy(); //settingsFile
       
   952     // close file
       
   953     fs.Close();
       
   954     }
       
   955 
       
   956 TInt CProfiler::CheckOldProfilerRunning()
       
   957     {
       
   958     TFindProcess procName;
       
   959     procName.Find(_L("BappeaProf.exe*"));
       
   960     TFullName aResult;
       
   961     TInt err(KErrNone);
       
   962     RProcess proc;    
       
   963     
       
   964     // now check if old Profiler is still running on
       
   965     err = procName.Next(aResult);
       
   966     // check if old profiler process found 
       
   967     if(err == KErrNone)
       
   968         {
       
   969         // other process found, i.e. right process to communicate with, in case started from eshell
       
   970         err = proc.Open(procName);
       
   971         if(err == KErrNone)
       
   972             {
       
   973             if(proc.ExitCategory().Length() > 0)
       
   974                 {
       
   975                 proc.Close();
       
   976                 // process already exited => create a new one
       
   977                 return KErrNotFound;
       
   978                 }
       
   979             proc.Close();
       
   980             }
       
   981         // return error for error handling
       
   982         return KErrAlreadyExists;
       
   983         }
       
   984     return err;
       
   985     }
       
   986 
       
   987 // --------------------------------------------------------------------------------------------
       
   988 void CProfiler::HandleError(TInt aErr)
       
   989     {
       
   990     // write error to status property to inform requester
       
   991     TInt err(iEngineStatus.Set(KEngineStatusPropertyCat, EProfilerEngineStatus, aErr));
       
   992     if(err != KErrNone)
       
   993         RDebug::Print(_L("CProfiler::HandleError() - error setting status: %d"), err);
       
   994     }
       
   995 
       
   996 // --------------------------------------------------------------------------------------------
       
   997 TInt CProfiler::ControlDataL(TInt aCommand,TAny* value1,TAny* /*value2*/)
       
   998     {
       
   999 	LOGSTRING3("CProfiler::ControlData %d, 0x%x",aCommand,value1);
       
  1000 
       
  1001 	_LIT(KDebugOutput, "debug_output");
       
  1002 	_LIT(KFileOutput, "file_system");
       
  1003 	_LIT8(KOutputToDebugOutput, "debug_output");
       
  1004 	
       
  1005 	TDes* desc;
       
  1006 	TPtrC ptrDesc;
       
  1007 	
       
  1008 	switch(aCommand)
       
  1009 	    {
       
  1010 		// new controls
       
  1011 	    case RProfiler::EGetFileName:
       
  1012 	        {
       
  1013             LOGTEXT(_L("Profiler::EGetFileName - start"));
       
  1014             LOGSTRING2(_L("Profiler::EGetFileName - total file name is: %S"),(TDes*)value1);
       
  1015             desc = (TDes*)value1;
       
  1016             desc->Zero();
       
  1017             desc->Append(iFileNameStream);
       
  1018             LOGSTRING2(_L("Profiler::EGetFileName - now total file name is: %S"),(TDes*)value1);
       
  1019             return KErrNone;
       
  1020 	        }
       
  1021         case RProfiler::EGetActiveWriter:
       
  1022             {
       
  1023             LOGTEXT(_L("Profiler::EGetActiveWriter - start"));
       
  1024             desc = (TDes*)value1;
       
  1025             desc->Zero();
       
  1026             if(iGeneralAttributes.iTraceOutput.CompareF(KOutputToDebugOutput) == 0)
       
  1027                 {
       
  1028                 desc->Append(KDebugOutput);
       
  1029                 }
       
  1030             else
       
  1031                 {
       
  1032                 desc->Append(KFileOutput);
       
  1033                 }
       
  1034             return KErrNone;
       
  1035             }
       
  1036 	    }
       
  1037 
       
  1038 	return KErrNone;
       
  1039     }
       
  1040 
       
  1041 // --------------------------------------------------------------------------------------------
       
  1042 TInt CProfiler::ControlL(TInt aCommand)
       
  1043     {
       
  1044 	LOGSTRING2("CProfiler::Control - Controlling ProfilerEngine %d",aCommand);
       
  1045 	TInt err(KErrNone);
       
  1046 	
       
  1047 	switch (aCommand)
       
  1048 	    {
       
  1049 		case RProfiler::EStartSampling:
       
  1050 		    {
       
  1051 		    // check first if old Profiler already running
       
  1052 		    err = CheckOldProfilerRunning();
       
  1053 		    if(err == KErrAlreadyExists)
       
  1054 		        {
       
  1055 		        // if exists do not start a profiling process since corrupts the collected trace data  
       
  1056 		        HandleError(err);
       
  1057 		        err = KErrNone;
       
  1058 		        return err;
       
  1059 		        }
       
  1060 		    
       
  1061 		    // save settings before launching the profiler
       
  1062 		    // reason: the profiling may have set to the background => need for get right settings
       
  1063 		    SaveSettingsL();
       
  1064 		    
       
  1065 		    // set the general settings to writer plugins to reflect the latest changes
       
  1066 		    err = HandleGeneralSettingsChange();
       
  1067 		    if(err == KErrNone)
       
  1068 		        {
       
  1069                 // reset the buffers before new profiling
       
  1070                 iUserStream->ResetBuffers();
       
  1071     
       
  1072                 // give the CProfilerSampleStream a handle to current writer
       
  1073                 iUserStream->SetWriter(*iWriterHandler->GetActiveWriter());
       
  1074                 
       
  1075                 // set initially debug output writer active
       
  1076                 err = iWriterHandler->StartSelectedPlugin();
       
  1077     
       
  1078                 // check that writer plugin started
       
  1079                 if(err != KErrNone)
       
  1080                     {
       
  1081                     // if not started handle error
       
  1082                     HandleError(err);
       
  1083                     }
       
  1084                 else
       
  1085                     {
       
  1086                     // start activated sampler plug-in, NOTE: plugins check if errors occur in startup for some reason
       
  1087                     iSamplerHandler->StartSamplerPluginsL();
       
  1088         
       
  1089                     // set engine state P&S property to running, e.g. for PIProfiler UI to read
       
  1090                     iState = RProfiler::ERunning;
       
  1091         
       
  1092                     // set the engine into running mode
       
  1093                     iEngineStatus.Set(iState);
       
  1094                     }
       
  1095                 }
       
  1096 		    else
       
  1097 		        {
       
  1098 		        // handle error and notify requester
       
  1099 		        HandleError(err);
       
  1100 		        }
       
  1101 		    
       
  1102 		    LOGTEXT(_L("CProfiler::Control - Finished processing EStartSampling!"));
       
  1103 
       
  1104 			return err;
       
  1105 		    }
       
  1106 		case RProfiler::EStopSampling:
       
  1107 			LOGTEXT(_L("CProfiler::Control - Starting to stop sampling..."));
       
  1108 			// stop sampler plugins
       
  1109 			if(iState == RProfiler::ERunning)
       
  1110 				{
       
  1111 				iState = RProfiler::EStopping;
       
  1112 				iEngineStatus.Set(RProfiler::EStopping);
       
  1113 				
       
  1114 				iSamplerHandler->StopSamplerPlugins();
       
  1115 	
       
  1116 				// finalize the filled buffer writing
       
  1117 				iUserStream->Finalise();
       
  1118 				
       
  1119 				// stop output plugin and write the rest of the trace data to output
       
  1120 				LOGTEXT(_L("CProfiler::Control - stopping writer"));
       
  1121 				iWriterHandler->StopSelectedPlugin();
       
  1122 	
       
  1123 				// set engine state P&S property idle 
       
  1124 				iState = RProfiler::EIdle;
       
  1125 				iEngineStatus.Set(RProfiler::EIdle);
       
  1126 				
       
  1127 				LOGSTRING2("CProfiler::Control - sampling stopped, going to state %d", RProfiler::EIdle);
       
  1128 				}
       
  1129 			return KErrNone;
       
  1130 
       
  1131 		case RProfiler::EExitProfiler:
       
  1132 		    {
       
  1133 		    // save settings into settings file when exiting
       
  1134 		    SaveSettingsL();
       
  1135 
       
  1136             if(iUserStream)
       
  1137                 {
       
  1138                 delete iUserStream;
       
  1139                 iUserStream = NULL;
       
  1140                 }
       
  1141 		    
       
  1142             // set engine state P&S property idle 
       
  1143             iState = RProfiler::EIdle;
       
  1144             iEngineStatus.Set(RProfiler::EIdle);
       
  1145                
       
  1146             LOGTEXT(_L("Stopping Activer Scheduler"));
       
  1147             CActiveScheduler::Stop();
       
  1148             LOGTEXT(_L("Stopped Activer Scheduler"));
       
  1149 
       
  1150             return KErrNone;
       
  1151 		    }
       
  1152 	    }
       
  1153 
       
  1154 	LOGTEXT(_L("CProfiler::Control - returning"));
       
  1155 
       
  1156 	return err;
       
  1157     }
       
  1158 
       
  1159 // --------------------------------------------------------------------------------------------
       
  1160 void CProfiler::Finalise()
       
  1161     {	
       
  1162 	LOGTEXT(_L("CProfiler::Finalise - Finished processing EStopSampling!"));
       
  1163     }
       
  1164 
       
  1165 // --------------------------------------------------------------------------------------------
       
  1166 RProfiler::TSamplerState CProfiler::State() const
       
  1167     {
       
  1168 	return iState;
       
  1169     }
       
  1170 
       
  1171 /*
       
  1172  *
       
  1173  *	Class CPServer definition
       
  1174  *
       
  1175  */
       
  1176 // --------------------------------------------------------------------------------------------
       
  1177 inline const CPServer& CPSession::Server() const
       
  1178     {
       
  1179 	return *static_cast<const CPServer*>(CSession2::Server());
       
  1180     }
       
  1181 
       
  1182 // --------------------------------------------------------------------------------------------
       
  1183 void CPSession::ServiceL(const RMessage2& aMessage)
       
  1184     {
       
  1185 	LOGTEXT(_L("CPSession::ServiceL - Starting to process message"));
       
  1186 	TInt err(KErrNone);
       
  1187 	
       
  1188 	if(aMessage.Function() == RProfiler::EGetGeneralAttributes)
       
  1189 	    {
       
  1190 	    Server().GetGeneralAttributesL(aMessage);
       
  1191 	    }
       
  1192 	else if(aMessage.Function() == RProfiler::ESetGeneralAttributes)
       
  1193 	    {
       
  1194         Server().SetGeneralAttributesL(aMessage);
       
  1195 	    }
       
  1196 	else if(aMessage.Function() == RProfiler::EGetSamplerAttributes)
       
  1197 	    {
       
  1198         Server().GetSamplerAttributesL(aMessage);
       
  1199 	    }
       
  1200     else if(aMessage.Function() == RProfiler::EGetSamplerAttributeCount)
       
  1201         {
       
  1202         Server().GetSamplerAttributeCountL(aMessage);
       
  1203         }
       
  1204     else if(aMessage.Function() == RProfiler::ESetSamplerAttributes)
       
  1205         {
       
  1206         Server().SetSamplerAttributesL(aMessage);
       
  1207         }
       
  1208     else if(aMessage.Function() == RProfiler::ERefreshProfilerStatus)
       
  1209         {
       
  1210         Server().RefreshStatus(aMessage);
       
  1211         }
       
  1212 	else if(aMessage.Ptr0() == 0 && aMessage.Ptr1() == 0 && aMessage.Ptr2() == 0)
       
  1213 		{	
       
  1214 		LOGTEXT(_L("Ptr0 && Ptr1 == 0 && Ptr2 == 0"));
       
  1215 		aMessage.Complete(Server().ControlL(RProfiler::TCommand(aMessage.Function())));
       
  1216 		LOGTEXT(_L("CPSession::ServiceL - Message completed"));
       
  1217 		} 
       
  1218 	else if(aMessage.Ptr0() != 0 && aMessage.Ptr1() != 0 && aMessage.Ptr2() != 0)
       
  1219 		{
       
  1220 		LOGTEXT(_L("Error with message, all pointers contain data!"));
       
  1221 		}
       
  1222 		
       
  1223 	else if (aMessage.Ptr0() != 0)
       
  1224 		{
       
  1225 		if(aMessage.Ptr1() == 0)
       
  1226 			{
       
  1227 			LOGTEXT(_L("ServiceL: Ptr0 != 0 && Ptr1 == 0"));
       
  1228 			// provided value is a descriptor
       
  1229 			TBuf<64>* dst = new TBuf<64>;
       
  1230 			aMessage.ReadL(0,*dst,0);
       
  1231 	
       
  1232 			err = Server().ControlDataL(aMessage.Function(),(TAny*)dst);
       
  1233 			delete dst;
       
  1234 			aMessage.Complete(err);
       
  1235 			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
       
  1236 			}
       
  1237 		else
       
  1238 			{
       
  1239 			LOGTEXT(_L("ServiceL: Ptr0 != 0 && Ptr1 != 0"));
       
  1240 			// provided value is a descriptor
       
  1241 			TBuf<64>* dst = new TBuf<64>;
       
  1242 			aMessage.ReadL(0,*dst,0);
       
  1243 			
       
  1244 			TUint32 num1 = (TUint32)aMessage.Ptr1();
       
  1245 			
       
  1246 			err = Server().ControlDataL(aMessage.Function(),(TAny*)dst, (TAny*)num1);
       
  1247 			delete dst;
       
  1248 			aMessage.Complete(err);
       
  1249 			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
       
  1250 			}
       
  1251 		}
       
  1252 	else if (aMessage.Ptr1() != 0)
       
  1253 		{
       
  1254 		LOGTEXT(_L("ServiceL: Ptr1 != 0"));
       
  1255 		// provided value is a TUint32
       
  1256 		if( ((TUint32)aMessage.Ptr3()) == 0xffffffff)
       
  1257 			{
       
  1258 			TUint32 num = (TUint32)aMessage.Ptr1();
       
  1259 			err = Server().ControlDataL(aMessage.Function(),(TAny*)num);
       
  1260 			aMessage.Complete(err);
       
  1261 			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
       
  1262 			}
       
  1263 		else
       
  1264 			{
       
  1265 			LOGTEXT(_L("ServiceL: Ptr3 != 0xffffffff"));
       
  1266 			TUint32 num1 = (TUint32)aMessage.Ptr1();
       
  1267 			TUint32 num2 = (TUint32)aMessage.Ptr3();
       
  1268 			err = Server().ControlDataL(aMessage.Function(),(TAny*)num1,(TAny*)num2);
       
  1269 			aMessage.Complete(err);
       
  1270 			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
       
  1271 			}
       
  1272 		}
       
  1273 	else if (aMessage.Ptr2() != 0)
       
  1274 		{
       
  1275 		// command requests for data, provided 
       
  1276 		// value should be a descriptor
       
  1277 		if( ((TUint32)aMessage.Ptr3()) == 0xffffffff)
       
  1278 			{
       
  1279 			LOGTEXT(_L("ServiceL: Ptr2 != 0 && Ptr3 == 0xffffffff"));
       
  1280 	
       
  1281 			TBuf<256>* src = new TBuf<256>;
       
  1282 			src->Zero();
       
  1283 			err = Server().ControlDataL(aMessage.Function(),(TAny*)src);
       
  1284 	
       
  1285 			LOGSTRING2("Got sampler data %S",src);
       
  1286 			
       
  1287 			aMessage.WriteL(2, *src, 0);
       
  1288 	
       
  1289 			delete src;
       
  1290 			aMessage.Complete(err);
       
  1291 			LOGTEXT(_L("CPSession::ServiceL - Message completed"));
       
  1292 			}
       
  1293 		else 
       
  1294 			{
       
  1295 			LOGTEXT(_L("ServiceL: Ptr2 != 0 && Ptr3 != 0xffffffff"));
       
  1296 			
       
  1297 			TUint32 num1 = (TUint32)aMessage.Ptr2();	// containing id
       
  1298 			TBuf<256>* buffer = new TBuf<256>;		// Text data, e.g. plug-in name or description
       
  1299 
       
  1300 			LOGSTRING3("Getting data for sampler: 0x%X, buffer max len %d",num1, aMessage.GetDesMaxLength(3));
       
  1301 
       
  1302 			err = Server().ControlDataL(aMessage.Function(), (TAny*)num1, (TAny*)buffer);
       
  1303 
       
  1304 			LOGSTRING2("Got sampler data %S",&buffer);
       
  1305 			
       
  1306 			// write back to same parameter
       
  1307 			aMessage.WriteL(3, *buffer, 0);
       
  1308 			aMessage.Complete(err);
       
  1309 			LOGTEXT(_L("CPSession::ServiceL - Message completed"));			
       
  1310 			}
       
  1311 		}
       
  1312 	LOGTEXT(_L("CPSession::ServiceL - Message processed"));
       
  1313     }
       
  1314 
       
  1315 // --------------------------------------------------------------------------------------------
       
  1316 MProfilerController* CPServer::NewL(TInt aPriority, MProfilerEngine& aEngine)
       
  1317     {
       
  1318 	LOGTEXT(_L("CPServer::NewL - Enter"));
       
  1319 	CPServer* self = new(ELeave) CPServer(aPriority, aEngine);
       
  1320 	CleanupStack::PushL(self);
       
  1321 	self->StartL(KProfilerName);
       
  1322 	CleanupStack::Pop();
       
  1323 	LOGTEXT(_L("CPSession::NewL - Exit"));
       
  1324 	return self;
       
  1325     }
       
  1326 
       
  1327 // --------------------------------------------------------------------------------------------
       
  1328 CPServer::CPServer(TInt aPriority, MProfilerEngine& aEngine)
       
  1329 	: CServer2(aPriority), MProfilerController(aEngine)
       
  1330     {
       
  1331 
       
  1332     }
       
  1333 
       
  1334 // --------------------------------------------------------------------------------------------
       
  1335 void CPServer::Release()
       
  1336     {
       
  1337 	delete this;
       
  1338     }
       
  1339 
       
  1340 // --------------------------------------------------------------------------------------------
       
  1341 CSession2* CPServer::NewSessionL(const TVersion&,const RMessage2&) const
       
  1342     {
       
  1343 	return new(ELeave) CPSession();
       
  1344     }
       
  1345 
       
  1346 /*
       
  1347  *
       
  1348  * Static methods for controlling the profiler
       
  1349  * through command line
       
  1350  *
       
  1351  */
       
  1352 // --------------------------------------------------------------------------------------------
       
  1353 static void RunEngineServerL(const TDesC& aSettingsFile)
       
  1354     {
       
  1355 	RDebug::Print(_L("Profiler: RunEngineServerL() - Install active scheduler"));
       
  1356 	CActiveScheduler* pS = new CActiveScheduler;
       
  1357 	CActiveScheduler::Install(pS);
       
  1358 	CProfiler* p = CProfiler::NewLC(aSettingsFile);
       
  1359 	CActiveScheduler::Start();
       
  1360 	p->Finalise();
       
  1361 	CleanupStack::PopAndDestroy(p);
       
  1362 	delete pS;
       
  1363     }
       
  1364 
       
  1365 // --------------------------------------------------------------------------------------------
       
  1366 static TInt TestSettingsFile(const TDesC& configFile)
       
  1367     {
       
  1368     RFs fs;
       
  1369     TBuf8<256> configFile8;
       
  1370     
       
  1371     // check if file server can be connected
       
  1372     if (fs.Connect() != KErrNone)
       
  1373         {
       
  1374         // file server couldn't be connected, return false
       
  1375         return KErrNotFound;
       
  1376         }
       
  1377 
       
  1378     // check if config file name length is > 0
       
  1379     if (configFile.Length() > 0)
       
  1380         {
       
  1381         // check sanity of settings file location
       
  1382         CnvUtfConverter::ConvertFromUnicodeToUtf8(configFile8, configFile);
       
  1383         if(!CProfiler::CheckLocationSanity(fs, configFile8))
       
  1384             {
       
  1385             fs.Close();
       
  1386             return KErrGeneral;
       
  1387             }
       
  1388         }
       
  1389     else
       
  1390         {
       
  1391         // configFile length 0, return false
       
  1392         fs.Close();
       
  1393         return KErrNotFound;
       
  1394         }
       
  1395     // return true if tests passed
       
  1396     fs.Close();
       
  1397     return KErrNone;
       
  1398     }
       
  1399 
       
  1400 // --------------------------------------------------------------------------------------------
       
  1401 GLDEF_C TInt E32Main()
       
  1402     {
       
  1403     // parse command line arguments 
       
  1404     TBuf<256> c;
       
  1405 
       
  1406     // copy the full command line with arguments into a buffer
       
  1407     User::CommandLine(c);
       
  1408 
       
  1409     TBuf<256> fileName;
       
  1410     fileName.Append(c); // only one settings param should be
       
  1411     LOGSTRING2("Filename is %S", &fileName);
       
  1412     if(TestSettingsFile(fileName) != KErrNone)
       
  1413         {
       
  1414         // settings file does not exist, copy null desc to file name
       
  1415         fileName.Copy(KNullDesC);
       
  1416         }
       
  1417     
       
  1418     // if no command line arguments found just start the profiler process
       
  1419     __UHEAP_MARK;
       
  1420     CTrapCleanup* cleanup = CTrapCleanup::New();
       
  1421     TInt ret(KErrNoMemory);
       
  1422     if( cleanup )
       
  1423         {
       
  1424         TRAPD( ret, RunEngineServerL(fileName) );
       
  1425         RDebug::Print(_L("Profiler: E32Main() - ret %d"), ret);
       
  1426         delete cleanup;
       
  1427         } 
       
  1428     __UHEAP_MARKEND;
       
  1429 
       
  1430     return ret;
       
  1431     } 
       
  1432 
       
  1433