perfmon/src/perfmon_model.cpp
branchRCL_3
changeset 22 fad26422216a
parent 0 d6fe6244b863
equal deleted inserted replaced
21:b3cee849fa46 22:fad26422216a
       
     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 FILES
       
    20 
       
    21 #include "perfmon_model.h"
       
    22 #include "perfmon_app.h"
       
    23 #include "perfmon_settingsviewdlg.h"
       
    24 #include "perfmon.hrh"
       
    25 #include "perfmon_valuescontainer.h"
       
    26 #include "perfmon_graphscontainer.h"
       
    27 #include "perfmon_datapopupcontainer.h"
       
    28 #include <perfmon.rsg>
       
    29 
       
    30 #include <coeutils.h>
       
    31 #include <bautils.h>
       
    32 #include <eikenv.h>
       
    33 #include <e32hal.h>
       
    34 #include <u32std.h>
       
    35 #include <s32file.h>
       
    36 #include <akntitle.h> 
       
    37 #include <eikspane.h>
       
    38 #include <aknnotewrappers.h>  
       
    39 
       
    40 _LIT(KAppName, "PerfMon");
       
    41 _LIT(KDefaultLogFilePath, "c:\\data\\PerfMon.log");
       
    42 
       
    43 const TInt KCalibrationLength = 2;
       
    44 const TInt KMinimumSamplesLength = 16;
       
    45 const TInt KCPUTimeMultiplier = 1000000; // used to avoid TReal conversions
       
    46 
       
    47 const TInt KSettingsDrive = EDriveC;
       
    48 _LIT(KSettingsFileName, "perfmon_settings.ini");
       
    49 
       
    50 
       
    51 // --------------------------------------------------------------------------------------------
       
    52 
       
    53 TInt CPULoadCount(TAny* aInt)
       
    54 	{
       
    55 	// increase the counter
       
    56 	(*(TUint*)aInt)++;
       
    57 	return 1;
       
    58 	}
       
    59 
       
    60 TInt CPULoadNOPThread(TAny* aParam)
       
    61 	{
       
    62 	CTrapCleanup* pC = CTrapCleanup::New();
       
    63 	CActiveScheduler* pS = new CActiveScheduler;
       
    64 	CActiveScheduler::Install(pS);
       
    65 
       
    66 	CIdle* idle = CIdle::NewL(CActive::EPriorityStandard);
       
    67 	TCallBack cb(CPULoadCount, aParam);
       
    68 	idle->Start(cb);
       
    69 
       
    70 	pS->Start();
       
    71 
       
    72 	delete idle;
       
    73 	delete pS;
       
    74 	delete pC;
       
    75 
       
    76 	return 0;
       
    77 	}
       
    78 
       
    79 // ===================================== MEMBER FUNCTIONS =====================================
       
    80 
       
    81 CPerfMonModel* CPerfMonModel::NewL()
       
    82 	{
       
    83 	CPerfMonModel* self = new(ELeave) CPerfMonModel;
       
    84 	CleanupStack::PushL(self);
       
    85 	self->ConstructL();
       
    86 	CleanupStack::Pop();
       
    87 	return self;
       
    88 	}
       
    89 
       
    90 // --------------------------------------------------------------------------------------------
       
    91 
       
    92 CPerfMonModel::CPerfMonModel() : CActive(EPriorityUserInput)
       
    93 	{
       
    94 	}
       
    95 
       
    96 // --------------------------------------------------------------------------------------------
       
    97 
       
    98 void CPerfMonModel::ConstructL()
       
    99 	{
       
   100 	iDrawState = EDrawStateInvalid;
       
   101 	iCurrentCPUMode = ECPUModeNotSet;
       
   102 	iLogFileInitialized = EFalse;
       
   103 	
       
   104     iEnv = CEikonEnv::Static();
       
   105     User::LeaveIfError(iLs.Connect());
       
   106 
       
   107     User::LeaveIfError(iTimer.CreateLocal());
       
   108 	CActiveScheduler::Add(this);
       
   109 	}
       
   110 
       
   111 // --------------------------------------------------------------------------------------------
       
   112 
       
   113 void CPerfMonModel::ActivateModelL()
       
   114 	{
       
   115     // load settings
       
   116     TRAP_IGNORE(LoadSettingsL());
       
   117 
       
   118 	// create data storages for the samples
       
   119 	CreateSamplesDataArrayL();
       
   120 	
       
   121 	// initialize the data popup container in top-right corner
       
   122 	iDataPopupContainer = new(ELeave) CPerfMonDataPopupContainer;
       
   123 	iDataPopupContainer->ConstructL(TRect(0,0,1,1));
       
   124 	
       
   125 	// set default modes
       
   126 	HandleSettingsChangeL();
       
   127 
       
   128     // start sampling data immediately (jump to RunL)    
       
   129     iTimer.After(iStatus, 100);
       
   130     SetActive();
       
   131 	}
       
   132 
       
   133 // --------------------------------------------------------------------------------------------
       
   134 
       
   135 void CPerfMonModel::DeActivateModelL()
       
   136 	{
       
   137 	Cancel();
       
   138 	
       
   139 	DeActivateCPUMonitoring();
       
   140 
       
   141 	if (iDataPopupContainer)
       
   142 	    {
       
   143 	    delete iDataPopupContainer;
       
   144 	    iDataPopupContainer = NULL;
       
   145 	    }
       
   146 
       
   147     // close log file
       
   148 	OpenLogFile(EFalse);
       
   149 	}
       
   150 	
       
   151 // --------------------------------------------------------------------------------------------
       
   152 
       
   153 CPerfMonModel::~CPerfMonModel()
       
   154 	{
       
   155 	iTimer.Close();
       
   156 
       
   157     // clear data storages
       
   158 	if (iSampleEntryArray)
       
   159 	    {
       
   160         for (TInt i=0; i<iSampleEntryArray->Count(); i++)
       
   161             {
       
   162             delete iSampleEntryArray->At(i).iSampleDataArray;
       
   163             }
       
   164 	    
       
   165 	    delete iSampleEntryArray;
       
   166 	    }
       
   167 
       
   168 	    
       
   169 	iLs.Close();
       
   170     }
       
   171 
       
   172 // --------------------------------------------------------------------------------------------
       
   173 
       
   174 void CPerfMonModel::DoCancel()
       
   175 	{
       
   176     iTimer.Cancel();
       
   177 	}
       
   178 
       
   179 // --------------------------------------------------------------------------------------------
       
   180 
       
   181 void CPerfMonModel::RunL()
       
   182 	{
       
   183 	// calculate new values 
       
   184 	UpdateSamplesDataL();
       
   185 	
       
   186 	// log changes
       
   187 	AppendLatestSamplesToLogsL();
       
   188 	
       
   189 	// redraw views
       
   190 	SendDrawEventToContainersL();  
       
   191 
       
   192     // continue
       
   193     iTimer.After(iStatus, iSettings.iHeartBeat * 1000); // convert from milliseconds to microseconds
       
   194     SetActive();
       
   195 	}
       
   196 
       
   197 // --------------------------------------------------------------------------------------------
       
   198 
       
   199 void CPerfMonModel::HandleSettingsChangeL()
       
   200     {
       
   201     // set priority of the thread
       
   202     RThread().SetPriority(SettingItemToThreadPriority(iSettings.iPriority));
       
   203     
       
   204     // set visibility and location of the data popup
       
   205     iDataPopupContainer->UpdateVisibility();
       
   206     iDataPopupContainer->SetPositionAndSize();
       
   207     
       
   208     // init cpu monitor if setting has been changed
       
   209     if (iCurrentCPUMode != iSettings.iCPUMode)
       
   210         {
       
   211         DeActivateCPUMonitoring();
       
   212         ActivateCPUMonitoringL();
       
   213         }
       
   214     
       
   215     // close log file
       
   216     OpenLogFile(EFalse);
       
   217     
       
   218     // enable log file
       
   219     if (iSettings.iLoggingEnabled && (iSettings.iLoggingMode == ELoggingModeLogFile || iSettings.iLoggingMode == ELoggingModeRDebugLogFile))
       
   220         OpenLogFile(ETrue);
       
   221     }
       
   222 
       
   223 // --------------------------------------------------------------------------------------------
       
   224 
       
   225 void CPerfMonModel::EnableLogging(TBool aEnable)
       
   226     {
       
   227     if (aEnable)
       
   228         {
       
   229         if (iSettings.iLoggingMode == ELoggingModeLogFile || iSettings.iLoggingMode == ELoggingModeRDebugLogFile)
       
   230             OpenLogFile(ETrue);
       
   231         
       
   232         iSettings.iLoggingEnabled = ETrue;
       
   233         }
       
   234     else // disable
       
   235         {
       
   236         iSettings.iLoggingEnabled = EFalse;
       
   237         OpenLogFile(EFalse);
       
   238         }
       
   239     }
       
   240 
       
   241 // --------------------------------------------------------------------------------------------
       
   242 
       
   243 void CPerfMonModel::OpenLogFile(TBool aOpen)
       
   244     {
       
   245     // open log file for writing
       
   246     if (aOpen)
       
   247         {
       
   248         if (!iLogFileInitialized)
       
   249             {
       
   250             TInt err(KErrNone);
       
   251             
       
   252             // open the log file for writing
       
   253             if (iLogFile.Open(iEnv->FsSession(), iSettings.iLoggingFilePath, EFileWrite) != KErrNone)
       
   254                 {
       
   255                 iEnv->FsSession().MkDirAll(iSettings.iLoggingFilePath);
       
   256                 err = iLogFile.Replace(iEnv->FsSession(), iSettings.iLoggingFilePath, EFileWrite);
       
   257                 }
       
   258             else
       
   259                 {
       
   260                 // file opens correctly, seek to the end
       
   261                 TInt fileSize=0;
       
   262                 iLogFile.Size(fileSize);
       
   263                 err = iLogFile.Seek(ESeekCurrent, fileSize);
       
   264                 }
       
   265             
       
   266             if (err == KErrNone)
       
   267                 {
       
   268                 iLogFileInitialized = ETrue;
       
   269                 }
       
   270             else
       
   271                 {
       
   272                 // show error
       
   273                 CAknErrorNote* note = new(ELeave) CAknErrorNote();
       
   274                 note->ExecuteLD(_L("Unable to create log file, check settings"));                
       
   275                 }
       
   276             }        
       
   277         }
       
   278 
       
   279     // close handle to log file
       
   280     else 
       
   281         {
       
   282         if (iLogFileInitialized)
       
   283             {
       
   284             iLogFile.Flush();
       
   285             iLogFile.Close();
       
   286             
       
   287             iLogFileInitialized = EFalse;
       
   288             }
       
   289         }
       
   290     }
       
   291     
       
   292 // --------------------------------------------------------------------------------------------
       
   293 
       
   294 void CPerfMonModel::ActivateCPUMonitoringL()
       
   295     {
       
   296     // reset counter variables
       
   297 	iCPULoadCalibrating = ETrue;
       
   298 	iCPULoadCalibrationCounter = 0;
       
   299 	iCPULoadMaxValue = 999999999;
       
   300 	iCPULoadPreviousValue = 1;
       
   301 	iCPULoadCounter = 0;
       
   302 
       
   303     // use null thread is cpu time is supported and the setting is on
       
   304     if (CPUTimeSupported() && iSettings.iCPUMode == ECPUModeCPUTime) 
       
   305         {
       
   306         // try to open handle to null thread
       
   307         if (OpenHandleToNullThread())
       
   308             {
       
   309             // handle is open, get initial value
       
   310             TTimeIntervalMicroSeconds time;
       
   311             iNullThread.GetCpuTime(time);
       
   312             iCPULoadPreviousValue = time.Int64();
       
   313             iPreviousTime.HomeTime();
       
   314             
       
   315             iCurrentCPUMode = ECPUModeCPUTime;
       
   316             return; // cpu time is succesfully in use           
       
   317             }
       
   318         }
       
   319 
       
   320     // otherwise use normal sampling with nops    
       
   321     iCurrentCPUMode = ECPUModeNotSet;
       
   322 
       
   323     // show a warning if cpu time cannot be taken in use
       
   324     if (iSettings.iCPUMode == ECPUModeCPUTime)
       
   325         {
       
   326         CAknInformationNote* note = new(ELeave) CAknInformationNote();
       
   327         note->ExecuteLD(_L("CPU Time not supported in this system, using NOPs sampling"));
       
   328         }
       
   329         
       
   330     // create a thread for CPU load monitoring
       
   331     User::LeaveIfError(iCPULoadThread.Create(_L("PerfMonCPULoad"), CPULoadNOPThread, 0x1000, 0x1000, 0x100000, &iCPULoadCounter));
       
   332     iCPULoadThread.SetPriority(EPriorityLess);
       
   333     iCPULoadThread.Resume();    
       
   334     
       
   335     iCurrentCPUMode = ECPUModeNOPs; // NOPs taken succesfully in use
       
   336     }
       
   337 
       
   338 // --------------------------------------------------------------------------------------------
       
   339 
       
   340 TBool CPerfMonModel::OpenHandleToNullThread()
       
   341     {
       
   342     // find the kernel process and then the null thread
       
   343     TFindProcess fp(_L("ekern.exe*"));
       
   344     
       
   345     TFullName kernelName;
       
   346     if (fp.Next(kernelName) == KErrNone)
       
   347         {
       
   348         // process found, append null thread identifier
       
   349         kernelName.Append(_L("::Null"));
       
   350         
       
   351         // find the thread
       
   352         TFindThread ft(kernelName);
       
   353 
       
   354         TFullName threadName;
       
   355         if (ft.Next(threadName) == KErrNone)
       
   356             {
       
   357             // open instance to the thread
       
   358             if (iNullThread.Open(threadName) != KErrNone)
       
   359                 return EFalse;                
       
   360             }
       
   361         }
       
   362     
       
   363     // process not found
       
   364     else
       
   365         return EFalse;
       
   366     
       
   367     // success!
       
   368     return ETrue;        
       
   369     }
       
   370 
       
   371 // --------------------------------------------------------------------------------------------
       
   372 
       
   373 void CPerfMonModel::DeActivateCPUMonitoring()
       
   374     {
       
   375     if (iCurrentCPUMode == ECPUModeCPUTime)
       
   376         {
       
   377         iNullThread.Close();
       
   378         }
       
   379     
       
   380     else if (iCurrentCPUMode == ECPUModeNOPs)    
       
   381         {
       
   382         // kill the cpu load thread
       
   383         iCPULoadThread.Kill(0);
       
   384         iCPULoadThread.Close();        
       
   385         } 
       
   386     }
       
   387 
       
   388 // --------------------------------------------------------------------------------------------
       
   389 
       
   390 TBool CPerfMonModel::CPUTimeSupported()
       
   391     {
       
   392     TTimeIntervalMicroSeconds time;
       
   393     TInt err = RThread().GetCpuTime(time);
       
   394     
       
   395     if (err == KErrNone && time.Int64() > 0)
       
   396         return ETrue;
       
   397     else
       
   398         return EFalse;
       
   399     }
       
   400 
       
   401 // --------------------------------------------------------------------------------------------
       
   402 
       
   403 TThreadPriority CPerfMonModel::SettingItemToThreadPriority(TInt aIndex)
       
   404     {
       
   405     TThreadPriority threadPriority = EPriorityNull;
       
   406     
       
   407     switch ( aIndex )
       
   408         {
       
   409         case EThreadPriorityTypeMuchLess:
       
   410             {
       
   411             threadPriority = EPriorityMuchLess; break;
       
   412             }
       
   413         case EThreadPriorityTypeLess:
       
   414             {
       
   415             threadPriority = EPriorityLess; break;
       
   416             }
       
   417         case EThreadPriorityTypeNormal:
       
   418             {
       
   419             threadPriority = EPriorityNormal; break;
       
   420             }
       
   421         case EThreadPriorityTypeMore:
       
   422             {
       
   423             threadPriority = EPriorityMore; break;
       
   424             }
       
   425         case EThreadPriorityTypeMuchMore:
       
   426             {
       
   427             threadPriority = EPriorityMuchMore; break;
       
   428             }
       
   429         case EThreadPriorityTypeRealTime:
       
   430             {
       
   431             threadPriority = EPriorityRealTime; break;
       
   432             }
       
   433         case EThreadPriorityTypeAbsoluteVeryLow:
       
   434             {
       
   435             threadPriority = EPriorityAbsoluteVeryLow; break;
       
   436             }
       
   437         case EThreadPriorityTypeAbsoluteLow:
       
   438             {
       
   439             threadPriority = EPriorityAbsoluteLow; break;
       
   440             }
       
   441         case EThreadPriorityTypeAbsoluteBackground:
       
   442             {
       
   443             threadPriority = EPriorityAbsoluteBackground; break;
       
   444             }
       
   445         case EThreadPriorityTypeAbsoluteForeground:
       
   446             {
       
   447             threadPriority = EPriorityAbsoluteForeground; break;
       
   448             }
       
   449         case EThreadPriorityTypeAbsoluteHigh:
       
   450             {
       
   451             threadPriority = EPriorityAbsoluteHigh; break;
       
   452             }
       
   453 
       
   454         default:
       
   455             {
       
   456             User::Panic(_L("Wrong tp index"), 276);
       
   457             break;
       
   458             }
       
   459         }
       
   460 
       
   461     return threadPriority;
       
   462     }
       
   463 
       
   464 // --------------------------------------------------------------------------------------------
       
   465 
       
   466 void CPerfMonModel::CreateSamplesDataArrayL()
       
   467     {
       
   468     TInt maxSamples = iSettings.iMaxSamples >= KMinimumSamplesLength ? iSettings.iMaxSamples : KMinimumSamplesLength;
       
   469 
       
   470     // create the data structure to store all samples
       
   471     iSampleEntryArray = new(ELeave) CSampleEntryArray(16);
       
   472 
       
   473     // add all source entries
       
   474     for (TInt i=0; i<ESourcesLength; i++)
       
   475         {
       
   476         TSampleEntry newSampleEntry;
       
   477         
       
   478         if (i == ESourceCPU)
       
   479             {
       
   480             newSampleEntry.iDescription.Copy(_L("CPU"));
       
   481             newSampleEntry.iUnitTypeShort.Copy(KNullDesC);
       
   482             newSampleEntry.iUnitTypeLong.Copy(KNullDesC);
       
   483             newSampleEntry.iDriveNumber = -1;
       
   484             newSampleEntry.iGraphColor = KRgbYellow;            
       
   485             }
       
   486         
       
   487         else if (i == ESourceRAM)
       
   488             {
       
   489             newSampleEntry.iDescription.Copy(_L("RAM"));
       
   490             newSampleEntry.iUnitTypeShort.Copy(_L("b"));
       
   491             newSampleEntry.iUnitTypeLong.Copy(_L("bytes"));
       
   492             newSampleEntry.iDriveNumber = -1;
       
   493             newSampleEntry.iGraphColor = KRgbGreen;            
       
   494             }        
       
   495         
       
   496         else //drives
       
   497             {
       
   498             TChar driveLetter = 'C' + i-ESourceC; // C is the first drive
       
   499 
       
   500             newSampleEntry.iDescription.Append(driveLetter);
       
   501             newSampleEntry.iDescription.Append(_L(":"));
       
   502             newSampleEntry.iUnitTypeShort.Copy(_L("b"));
       
   503             newSampleEntry.iUnitTypeLong.Copy(_L("bytes"));
       
   504             
       
   505             iEnv->FsSession().CharToDrive(driveLetter, newSampleEntry.iDriveNumber);
       
   506             
       
   507             newSampleEntry.iGraphColor = KRgbCyan;
       
   508             newSampleEntry.iGraphColor.SetGreen(255-(i-ESourceC)*30);
       
   509             newSampleEntry.iGraphColor.SetRed(i*30);
       
   510             }
       
   511         
       
   512         newSampleEntry.iSampleDataArray = new(ELeave) CSampleDataArray(maxSamples); 
       
   513         
       
   514         iSampleEntryArray->AppendL(newSampleEntry);        
       
   515         }
       
   516 
       
   517     // save current time as start time
       
   518     iStartTime.HomeTime();
       
   519     }
       
   520 	
       
   521 // --------------------------------------------------------------------------------------------
       
   522 
       
   523 void CPerfMonModel::UpdateSamplesDataL()
       
   524     {
       
   525     // reset inactivity timers
       
   526     if (iSettings.iKeepBacklightOn)
       
   527         User::ResetInactivityTime();
       
   528    
       
   529     // get current time
       
   530     TTime currentTime;
       
   531     currentTime.HomeTime();
       
   532     
       
   533     // calculate time difference
       
   534     TTimeIntervalMicroSeconds timeDeltaFromPreviousSample = currentTime.MicroSecondsFrom(iPreviousTime);
       
   535     
       
   536     // remember current time as previous
       
   537     iPreviousTime = currentTime;
       
   538     
       
   539     
       
   540     // get CPU
       
   541     TInt64 cpuLoadDelta(0);
       
   542     TInt64 cpuLoadFree(0);
       
   543     TInt64 cpuLoadSize(0);
       
   544     TInt64 currentCPUValue(0);
       
   545     
       
   546     if (iCurrentCPUMode == ECPUModeCPUTime || iCurrentCPUMode == ECPUModeNOPs)
       
   547         {
       
   548         if (iCurrentCPUMode == ECPUModeCPUTime)
       
   549             {
       
   550             TTimeIntervalMicroSeconds time;
       
   551             iNullThread.GetCpuTime(time);
       
   552             currentCPUValue = time.Int64();
       
   553             }
       
   554         else if (iCurrentCPUMode == ECPUModeNOPs)
       
   555             {
       
   556             currentCPUValue = iCPULoadCounter;
       
   557             }    
       
   558             
       
   559         // get delta and store the previous value
       
   560         cpuLoadDelta = currentCPUValue - iCPULoadPreviousValue;
       
   561         iCPULoadPreviousValue = currentCPUValue;
       
   562         
       
   563         // velocity = distance / time
       
   564         cpuLoadFree = cpuLoadDelta * KCPUTimeMultiplier / timeDeltaFromPreviousSample.Int64();
       
   565         
       
   566 
       
   567         // detect maximum value
       
   568         if (cpuLoadFree > iCPULoadMaxValue)
       
   569             iCPULoadMaxValue = cpuLoadFree;
       
   570      
       
   571         
       
   572         // check calibration status      
       
   573     	if (iCPULoadCalibrating)
       
   574     	    {
       
   575     	    iCPULoadCalibrationCounter++;        
       
   576             cpuLoadSize = cpuLoadFree;
       
   577             
       
   578             // check if need to calibrate anymore
       
   579      	    if (iCPULoadCalibrationCounter > KCalibrationLength)
       
   580     	        {
       
   581     	        iCPULoadCalibrating = EFalse;
       
   582     	        
       
   583                 // from the samples, get the minimum value, and let it be the max value 
       
   584         		for (TInt i=0; i<iSampleEntryArray->At(0).iSampleDataArray->Count(); i++)
       
   585         		    {
       
   586         		    TInt64 newCPULoadMaxValue = iCPULoadMaxValue;
       
   587         		    
       
   588         		    if (iSampleEntryArray->At(0).iSampleDataArray->At(i).iFree < newCPULoadMaxValue)
       
   589         		        {
       
   590         		        newCPULoadMaxValue = iSampleEntryArray->At(0).iSampleDataArray->At(i).iFree;
       
   591         		        }
       
   592         		    
       
   593         		    iCPULoadMaxValue = newCPULoadMaxValue;     		    
       
   594         		    }	        
       
   595     	        
       
   596     	        // adjust priority of the poller thread
       
   597                 if (iCurrentCPUMode == ECPUModeNOPs)
       
   598                     {
       
   599                     iCPULoadThread.SetPriority(EPriorityAbsoluteVeryLow);
       
   600                     }    	        
       
   601     	        }
       
   602 
       
   603     	    }
       
   604     	else
       
   605     	    {
       
   606             cpuLoadSize = iCPULoadMaxValue;
       
   607     	    }            
       
   608         }
       
   609 
       
   610 	
       
   611 	// save cpu sample data    
       
   612     TSampleData cpuSample;
       
   613     cpuSample.iFree = cpuLoadFree;
       
   614     cpuSample.iSize = cpuLoadSize;
       
   615     cpuSample.iTimeFromStart = currentTime.MicroSecondsFrom(iStartTime);
       
   616 
       
   617     iSampleEntryArray->At(0).iSampleDataArray->InsertL(0, cpuSample);
       
   618     
       
   619  
       
   620     
       
   621     // get ram memory
       
   622     TMemoryInfoV1Buf ramMemory;
       
   623     UserHal::MemoryInfo(ramMemory);
       
   624     
       
   625     TSampleData memorySample;
       
   626     memorySample.iFree = ramMemory().iFreeRamInBytes;
       
   627     memorySample.iSize = ramMemory().iMaxFreeRamInBytes;
       
   628     memorySample.iTimeFromStart = currentTime.MicroSecondsFrom(iStartTime);
       
   629 
       
   630     iSampleEntryArray->At(1).iSampleDataArray->InsertL(0, memorySample); 
       
   631     
       
   632     
       
   633     // all drives
       
   634     for (TInt i=2; i<iSampleEntryArray->Count(); i++)
       
   635         {
       
   636         TSampleData driveSample;
       
   637         
       
   638         // get volume info from RFs
       
   639         TVolumeInfo volumeInfo;
       
   640         if (iEnv->FsSession().Volume(volumeInfo, iSampleEntryArray->At(i).iDriveNumber) == KErrNone)
       
   641             {
       
   642             driveSample.iFree = volumeInfo.iFree;
       
   643             driveSample.iSize = volumeInfo.iSize;
       
   644             }
       
   645         else
       
   646             {
       
   647             driveSample.iFree = 0;
       
   648             driveSample.iSize = 0;
       
   649             }    
       
   650 
       
   651         driveSample.iTimeFromStart = currentTime.MicroSecondsFrom(iStartTime);
       
   652     
       
   653         iSampleEntryArray->At(i).iSampleDataArray->InsertL(0, driveSample); 
       
   654         }
       
   655     
       
   656     
       
   657     // compress sample data arrays to save memory
       
   658     TInt curLength(iSampleEntryArray->At(0).iSampleDataArray->Count());
       
   659     
       
   660     TInt maxSamples = iSettings.iMaxSamples >= KMinimumSamplesLength ? iSettings.iMaxSamples : KMinimumSamplesLength;
       
   661     
       
   662     if (curLength > maxSamples && curLength % 5 == 0)
       
   663         {
       
   664         for (TInt i=0; i<iSampleEntryArray->Count(); i++)
       
   665             {
       
   666             iSampleEntryArray->At(i).iSampleDataArray->ResizeL(maxSamples); // looses old samples
       
   667             iSampleEntryArray->At(i).iSampleDataArray->Compress();
       
   668             }         
       
   669         }
       
   670     }
       
   671 
       
   672 // --------------------------------------------------------------------------------------------
       
   673     
       
   674 void CPerfMonModel::AppendLatestSamplesToLogsL()
       
   675     {
       
   676     if (iSettings.iLoggingEnabled && SampleEntryArray())
       
   677         {
       
   678         // loop all sources
       
   679         for (TInt i=0; i<SampleEntryArray()->Count(); i++)
       
   680             {
       
   681             // check if this setting has been enabled and it has some data
       
   682             if (iSettings.iLoggingSources.iSrcEnabled[i] && SampleEntryArray()->At(i).iSampleDataArray->Count() > 0)
       
   683                 {
       
   684                 // get current sample
       
   685                 TSampleData& currentSample = SampleEntryArray()->At(i).iSampleDataArray->At(0);
       
   686                 
       
   687                 TBuf<128> buf;
       
   688                 buf.Append(_L("PERFMON;"));
       
   689                 buf.Append(SampleEntryArray()->At(i).iDescription);
       
   690                 buf.Append(_L(";"));
       
   691                 buf.AppendNum(currentSample.iTimeFromStart.Int64());
       
   692                 buf.Append(_L(";"));
       
   693                 buf.AppendNum(currentSample.iFree);
       
   694                 buf.Append(_L(";"));
       
   695                 buf.AppendNum(currentSample.iSize);
       
   696 
       
   697                 // print to RDebug
       
   698                 if (iSettings.iLoggingMode == ELoggingModeRDebug || iSettings.iLoggingMode == ELoggingModeRDebugLogFile)
       
   699                     {
       
   700                     RDebug::Print(buf);
       
   701                     }
       
   702                 
       
   703                 // print to log file
       
   704                 if (iSettings.iLoggingMode == ELoggingModeLogFile || iSettings.iLoggingMode == ELoggingModeRDebugLogFile)
       
   705                     {
       
   706                     buf.Append(_L("\r\n"));
       
   707                     
       
   708                     TBuf8<128> buf8;
       
   709                     buf8.Copy(buf);
       
   710                     
       
   711                     iLogFile.Write(buf8);
       
   712                     }        
       
   713                 }
       
   714             }
       
   715         }
       
   716     }
       
   717 
       
   718 // --------------------------------------------------------------------------------------------
       
   719 
       
   720 void CPerfMonModel::SetValuesContainer(CPerfMonValuesContainer* aContainer)
       
   721     {
       
   722     iValuesContainer = aContainer;
       
   723     iDrawState = EDrawStateValues;
       
   724     }
       
   725 
       
   726 // --------------------------------------------------------------------------------------------
       
   727 
       
   728 void CPerfMonModel::SetGraphsContainer(CPerfMonGraphsContainer* aContainer)
       
   729     {
       
   730     iGraphsContainer = aContainer;
       
   731     iDrawState = EDrawStateGraphs;
       
   732     }
       
   733     
       
   734 // --------------------------------------------------------------------------------------------
       
   735 
       
   736 void CPerfMonModel::SendDrawEventToContainersL()
       
   737     {
       
   738     if (iDrawState == EDrawStateValues && iValuesContainer)
       
   739         iValuesContainer->DrawUpdate();
       
   740     else if (iDrawState == EDrawStateGraphs && iGraphsContainer)
       
   741         iGraphsContainer->DrawUpdate();
       
   742            
       
   743     if (iDataPopupContainer)
       
   744         iDataPopupContainer->DrawUpdate();
       
   745     }
       
   746             
       
   747 // --------------------------------------------------------------------------------------------
       
   748 
       
   749 void CPerfMonModel::LoadSettingsL()
       
   750     {
       
   751     // set defaults
       
   752     iSettings.iHeartBeat = 600;
       
   753     iSettings.iMaxSamples = 64;
       
   754     iSettings.iPriority = EThreadPriorityTypeNormal;
       
   755     iSettings.iCPUMode = ECPUModeCPUTime;
       
   756     iSettings.iKeepBacklightOn = ETrue;
       
   757 
       
   758     iSettings.iDataPopupVisibility = EDataPopupVisbilityAlwaysOn;
       
   759     iSettings.iDataPopupLocation = EDataPopupLocationTopRight;
       
   760     iSettings.iDataPopupSources.SetDefaults1();
       
   761 
       
   762     iSettings.iGraphsVerticalBarPeriod = 5;
       
   763     iSettings.iGraphsSources.SetDefaults2();
       
   764 
       
   765     iSettings.iLoggingMode = ELoggingModeRDebug;
       
   766     iSettings.iLoggingFilePath.Copy(KDefaultLogFilePath);
       
   767     iSettings.iLoggingSources.SetDefaults2();
       
   768     
       
   769     iSettings.iLoggingEnabled = EFalse;
       
   770 
       
   771 
       
   772     // make sure that the private path of this app in c-drive exists
       
   773     iEnv->FsSession().CreatePrivatePath( KSettingsDrive ); // c:\\private\\20011385\\
       
   774     
       
   775     // handle settings always in the private directory 
       
   776     if (iEnv->FsSession().SetSessionToPrivate( KSettingsDrive ) == KErrNone)
       
   777         {
       
   778         // open or create a dictionary file store
       
   779         CDictionaryFileStore* settingsStore = CDictionaryFileStore::OpenLC(iEnv->FsSession(), KSettingsFileName, KUidPerfMon);
       
   780 
       
   781         LoadDFSValueL(settingsStore, KPMSettingHeartBeat,                   iSettings.iHeartBeat);
       
   782         LoadDFSValueL(settingsStore, KPMSettingMaxSamples,                  iSettings.iMaxSamples);
       
   783         LoadDFSValueL(settingsStore, KPMSettingPriority,                    iSettings.iPriority);
       
   784         LoadDFSValueL(settingsStore, KPMSettingCPUMode,                     iSettings.iCPUMode);
       
   785         LoadDFSValueL(settingsStore, KPMSettingKeepBackLightOn,             iSettings.iKeepBacklightOn);
       
   786 
       
   787         LoadDFSValueL(settingsStore, KPMSettingDataPopupVisbility,          iSettings.iDataPopupVisibility);
       
   788         LoadDFSValueL(settingsStore, KPMSettingDataPopupLocation,           iSettings.iDataPopupLocation);
       
   789         LoadDFSValueL(settingsStore, KPMSettingDataPopupSources,            iSettings.iDataPopupSources);
       
   790 
       
   791         LoadDFSValueL(settingsStore, KPMSettingGraphsVerticalBarPeriod,     iSettings.iGraphsVerticalBarPeriod);
       
   792         LoadDFSValueL(settingsStore, KPMSettingGraphsSources,               iSettings.iGraphsSources);
       
   793 
       
   794         LoadDFSValueL(settingsStore, KPMSettingLoggingMode,                 iSettings.iLoggingMode);
       
   795         LoadDFSValueL(settingsStore, KPMSettingLoggingFilePath,             iSettings.iLoggingFilePath);
       
   796         LoadDFSValueL(settingsStore, KPMSettingLoggingSources,              iSettings.iLoggingSources);
       
   797 
       
   798         CleanupStack::PopAndDestroy(); // settingsStore         
       
   799         }
       
   800     }
       
   801 
       
   802 // --------------------------------------------------------------------------------------------
       
   803 
       
   804 void CPerfMonModel::SaveSettingsL()
       
   805     {
       
   806     // handle settings always in c:\\private\\20011385\\
       
   807     if (iEnv->FsSession().SetSessionToPrivate( KSettingsDrive ) == KErrNone)
       
   808         {
       
   809         // delete existing store to make sure that it is clean and not eg corrupted
       
   810         if (BaflUtils::FileExists(iEnv->FsSession(), KSettingsFileName))
       
   811             {
       
   812             iEnv->FsSession().Delete(KSettingsFileName);
       
   813             }
       
   814         
       
   815         // create a dictionary file store
       
   816         CDictionaryFileStore* settingsStore = CDictionaryFileStore::OpenLC(iEnv->FsSession(), KSettingsFileName, KUidPerfMon);
       
   817 
       
   818         SaveDFSValueL(settingsStore, KPMSettingHeartBeat,                   iSettings.iHeartBeat);
       
   819         SaveDFSValueL(settingsStore, KPMSettingMaxSamples,                  iSettings.iMaxSamples);
       
   820         SaveDFSValueL(settingsStore, KPMSettingPriority,                    iSettings.iPriority);
       
   821         SaveDFSValueL(settingsStore, KPMSettingCPUMode,                     iSettings.iCPUMode);
       
   822         SaveDFSValueL(settingsStore, KPMSettingKeepBackLightOn,             iSettings.iKeepBacklightOn);
       
   823 
       
   824         SaveDFSValueL(settingsStore, KPMSettingDataPopupVisbility,          iSettings.iDataPopupVisibility);
       
   825         SaveDFSValueL(settingsStore, KPMSettingDataPopupLocation,           iSettings.iDataPopupLocation);
       
   826         SaveDFSValueL(settingsStore, KPMSettingDataPopupSources,            iSettings.iDataPopupSources);
       
   827 
       
   828         SaveDFSValueL(settingsStore, KPMSettingGraphsVerticalBarPeriod,     iSettings.iGraphsVerticalBarPeriod);
       
   829         SaveDFSValueL(settingsStore, KPMSettingGraphsSources,               iSettings.iGraphsSources);
       
   830 
       
   831         SaveDFSValueL(settingsStore, KPMSettingLoggingMode,                 iSettings.iLoggingMode);
       
   832         SaveDFSValueL(settingsStore, KPMSettingLoggingFilePath,             iSettings.iLoggingFilePath);
       
   833         SaveDFSValueL(settingsStore, KPMSettingLoggingSources,              iSettings.iLoggingSources);
       
   834        
       
   835         settingsStore->CommitL();
       
   836         CleanupStack::PopAndDestroy(); // settingsStore             
       
   837         }
       
   838     }
       
   839     	
       
   840 // --------------------------------------------------------------------------------------------
       
   841 
       
   842 TInt CPerfMonModel::LaunchSettingsDialogL()
       
   843     {
       
   844     // launch the settings dialog
       
   845     TPerfMonSettings newSettings = iSettings;
       
   846     
       
   847     CPerfMonSettingsViewDlg* dlg = CPerfMonSettingsViewDlg::NewL(newSettings);
       
   848     TInt returnValue = dlg->ExecuteLD(R_PERFMON_SETTINGS_DIALOG);
       
   849     
       
   850     // always save settings since the settings dialog does not provide a possibility to cancel
       
   851     iSettings = newSettings;
       
   852     SaveSettingsL();
       
   853     HandleSettingsChangeL();
       
   854 
       
   855     // make sure that the title of the application is correct
       
   856     CEikStatusPane* sp = iEnv->AppUiFactory()->StatusPane();
       
   857     CAknTitlePane* tp = static_cast<CAknTitlePane*>( sp->ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) );
       
   858     tp->SetTextL(KAppName);
       
   859     
       
   860     return returnValue;
       
   861     }
       
   862 	
       
   863 // ---------------------------------------------------------------------------
       
   864 
       
   865 void CPerfMonModel::LoadDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, TInt& aValue)
       
   866     {
       
   867     if (aDicFS->IsPresentL(aUid))
       
   868         {
       
   869         RDictionaryReadStream in;
       
   870         in.OpenLC(*aDicFS, aUid);
       
   871         aValue = in.ReadInt16L();
       
   872         CleanupStack::PopAndDestroy(); // in        
       
   873         }
       
   874     }
       
   875 
       
   876 // ---------------------------------------------------------------------------
       
   877 
       
   878 void CPerfMonModel::LoadDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, TDes& aValue)
       
   879     {
       
   880     if (aDicFS->IsPresentL(aUid))
       
   881         {
       
   882         RDictionaryReadStream in;
       
   883         in.OpenLC(*aDicFS, aUid);
       
   884         TInt bufLength = in.ReadInt16L();   // get length of descriptor
       
   885         in.ReadL(aValue, bufLength);        // get the descriptor itself
       
   886         CleanupStack::PopAndDestroy(); // in
       
   887         }
       
   888     }
       
   889 
       
   890 // ---------------------------------------------------------------------------
       
   891 
       
   892 void CPerfMonModel::LoadDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, TPerfMonSources& aValue)
       
   893     {
       
   894     if (aDicFS->IsPresentL(aUid))
       
   895         {
       
   896         RDictionaryReadStream in;
       
   897         in.OpenLC(*aDicFS, aUid);
       
   898         TInt bufLength = in.ReadInt16L();   // get length of the array
       
   899         
       
   900         if (bufLength < 0 || bufLength > ESourcesLength)     // check for validaty
       
   901             User::Leave(KErrNotSupported);
       
   902         
       
   903         for (TInt i=0; i<bufLength; i++)    // get all items
       
   904             aValue.iSrcEnabled[i] = in.ReadInt16L();
       
   905         
       
   906         CleanupStack::PopAndDestroy(); // in
       
   907         }
       
   908     }
       
   909     
       
   910 // ---------------------------------------------------------------------------
       
   911 
       
   912 void CPerfMonModel::SaveDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, const TInt& aValue)
       
   913     {
       
   914     RDictionaryWriteStream out;
       
   915     out.AssignLC(*aDicFS, aUid);
       
   916     out.WriteInt16L(aValue);
       
   917     out.CommitL(); 	
       
   918     CleanupStack::PopAndDestroy(); // out
       
   919     }
       
   920 
       
   921 // ---------------------------------------------------------------------------
       
   922 
       
   923 void CPerfMonModel::SaveDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, const TDes& aValue)
       
   924     {
       
   925     RDictionaryWriteStream out;
       
   926     out.AssignLC(*aDicFS, aUid);
       
   927     out.WriteInt16L(aValue.Length());       // write length of the descriptor
       
   928     out.WriteL(aValue, aValue.Length());    // write the descriptor itself
       
   929     out.CommitL(); 	
       
   930     CleanupStack::PopAndDestroy(); // out
       
   931     }
       
   932 
       
   933 // ---------------------------------------------------------------------------
       
   934 
       
   935 void CPerfMonModel::SaveDFSValueL(CDictionaryFileStore* aDicFS, const TUid& aUid, const TPerfMonSources& aValue)
       
   936     {
       
   937     RDictionaryWriteStream out;
       
   938     out.AssignLC(*aDicFS, aUid);
       
   939     
       
   940     out.WriteInt16L(ESourcesLength);        // write length of the array
       
   941     
       
   942     for (TInt i=0; i<ESourcesLength; i++)   // write all items
       
   943         out.WriteInt16L(aValue.iSrcEnabled[i]);
       
   944     
       
   945     out.CommitL(); 	
       
   946     CleanupStack::PopAndDestroy(); // out
       
   947     }
       
   948     
       
   949 // ---------------------------------------------------------------------------
       
   950     
       
   951 // End of File