piprofiler/engine/src/ProfilerEshell.cpp
changeset 22 a009639409f5
child 49 7fdc9a71d314
equal deleted inserted replaced
17:67c6ff54ec25 22:a009639409f5
       
     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 #include <f32file.h>
       
    19 #include <e32cons.h>
       
    20 
       
    21 #include "ProfilerEshell.h"
       
    22 #include <piprofiler/ProfilerSession.h>
       
    23 
       
    24 
       
    25 
       
    26 _LIT(KProfilerEngineExe, "PIProfilerEngine.exe");
       
    27 
       
    28 /*
       
    29  *
       
    30  * Static methods for controlling the profiler
       
    31  * through command line
       
    32  *
       
    33  */
       
    34 // --------------------------------------------------------------------------------------------
       
    35 static void PrintUsageInfo(const TDesC& aAdditionalInfo)
       
    36     {
       
    37     _LIT(KConsoleName, "Console");
       
    38     _LIT(KLegalNote, "PIProfiler Version 2.2.0.2 Copyright @ 2009 Nokia\n");
       
    39     _LIT(KUsageNote, "Usage: PIProfiler [start/end/timed] settingsfile [time to run]\n");
       
    40     _LIT(KExample, "Example: PIProfiler timed C:\\data\\piprofilersettings.txt 60\n");
       
    41 
       
    42     TRAP_IGNORE(CConsoleBase* console = Console::NewL(KConsoleName,TSize(KConsFullScreen,KConsFullScreen));
       
    43         console->Printf(KLegalNote);
       
    44         console->Printf(KUsageNote);
       
    45         console->Printf(KExample);
       
    46         console->Write(aAdditionalInfo);
       
    47     
       
    48         console->Printf(_L("\n[Press any key]"));
       
    49         console->Getch();
       
    50         delete console;);
       
    51     }
       
    52 
       
    53 // --------------------------------------------------------------------------------------------
       
    54 static TInt FindProcess()
       
    55     {
       
    56     TFindProcess procName;
       
    57     procName.Find(_L("PIProfilerEngine.exe*"));
       
    58     TFullName aResult;
       
    59     
       
    60     // find the first appearance, i.e. "myself"...
       
    61     TInt err(procName.Next(aResult));  // the first appearance
       
    62     if(err == KErrNotFound)
       
    63         {
       
    64         // now check if old Profiler is still running on
       
    65         procName.Find(_L("BappeaProf.exe*"));
       
    66         err = procName.Next(aResult);
       
    67         // check if old profiler process found 
       
    68         if(err == KErrNone)
       
    69             {
       
    70             // return error for error handling
       
    71             return KErrAlreadyExists;
       
    72             }
       
    73         // return KErrNotFound and a new profiler engine process can be started
       
    74         return KErrNotFound;
       
    75         }
       
    76     return err;
       
    77     }
       
    78 
       
    79 /**
       
    80  * Function for starting profiler engine in the background,
       
    81  * call profiler to load settings
       
    82  * and start sampling process
       
    83  * 
       
    84  * @param configFile name and location of settings file
       
    85  * @param aRunTimeInSeconds run time in seconds
       
    86  * @param aBootTime run boot time sampling or not.
       
    87  */
       
    88 // --------------------------------------------------------------------------------------------
       
    89 static TInt StartProfilerProcess(const TDesC& configFile, TInt aRunTimeInSeconds, TBool aBootTime)
       
    90     {
       
    91     TInt err(KErrNone);
       
    92     RProcess proc;
       
    93     TRequestStatus status = KRequestPending;
       
    94     TBuf<256> conf;
       
    95     conf.Zero();
       
    96     conf.Append(configFile);
       
    97     if(aBootTime)
       
    98         {
       
    99         RDebug::Printf("boot time measurement");
       
   100         conf.Append(_L(" "));
       
   101         conf.Append(_L("boot"));
       
   102         }
       
   103     RDebug::RawPrint(conf);
       
   104     // check if process exists
       
   105     err = FindProcess();
       
   106     LOGSTRING2("PIProfiler: tried to find process, response %d", err); 
       
   107 
       
   108     // check if already exists and don't start a new eshell profiling
       
   109     if( err == KErrNotFound )
       
   110         {
       
   111         // try create new process
       
   112         err = proc.Create(KProfilerEngineExe, conf);
       
   113 
       
   114         LOGSTRING2("PIProfiler: created process, response %d", err); 
       
   115 
       
   116         // check if RProcess::Create() succeeded
       
   117         if( err == KErrNone )
       
   118             {
       
   119             // Trigger rendezvous on the supplied TRequestStatus object
       
   120             proc.Rendezvous(status); 
       
   121 
       
   122             // kick off the engine process
       
   123             proc.Resume();
       
   124             
       
   125             // wait for the constructor to complete 
       
   126             User::WaitForRequest(status); 
       
   127             
       
   128             // just lose the handle
       
   129             proc.Close();
       
   130             
       
   131             // start sampling, using settings found in settings file or if not found the default settings
       
   132             err = RProfiler::StartSampling();
       
   133             // check if command succesful
       
   134             if( err != KErrNone )
       
   135                 {
       
   136                 LOGSTRING2("PI Profiler start: err %d", err);
       
   137                 _LIT(KNoteProfilerCannotStart, "PI Profiler: cannot start PI Profiler, check settings!");
       
   138                 PrintUsageInfo(KNoteProfilerCannotStart);
       
   139                 
       
   140                 // check if process still alive
       
   141                 if(err != KErrNotFound)
       
   142                     {
       
   143                     // exit the profiler process since process was started
       
   144                     RProfiler::ExitProfiler();
       
   145                     }
       
   146                 return err;
       
   147                 }
       
   148             
       
   149             if(aRunTimeInSeconds > 0)
       
   150                 {
       
   151                 RDebug::Print(_L("Profiler running for %d s... "), aRunTimeInSeconds);
       
   152                 User::After(aRunTimeInSeconds*1000000);
       
   153                 RDebug::Print(_L("************* Profiler process closing *********"));
       
   154         
       
   155                 // stop sampling process
       
   156                 err = RProfiler::StopSampling();
       
   157                 // check if command succesfull
       
   158                 if( err != KErrNone )
       
   159                     {
       
   160                     LOGTEXT(_L("Profiler: could not connect engine, stop failed"));
       
   161                     return err;
       
   162                     }
       
   163                 
       
   164                 // exit the profiler process
       
   165                 err = RProfiler::ExitProfiler();
       
   166                 // check if command succesfull
       
   167                 if( err != KErrNone )
       
   168                     {
       
   169                     LOGTEXT(_L("Profiler: could not connect engine, exit failed"));
       
   170                     return err;
       
   171                     }
       
   172                 }
       
   173             } 
       
   174         else
       
   175             {
       
   176             _LIT(KNoteCannotFindProfiler, "PI Profiler: could not find PIProfilerEngine.exe");
       
   177             PrintUsageInfo(KNoteCannotFindProfiler);
       
   178             }
       
   179         }
       
   180     // check if old Profiler is already running
       
   181     else if( err == KErrAlreadyExists )
       
   182         {
       
   183         _LIT(KNoteAlreadyRunning, "PI Profiler: old Profiler process already running, close it down before launching the new!");
       
   184         PrintUsageInfo(KNoteAlreadyRunning);
       
   185         }
       
   186     // otherwise show error note
       
   187     else
       
   188         {
       
   189         _LIT(KNoteAlreadyRunning, "PI Profiler: already running, not able to launch new one. NOTE: check if UI running!");
       
   190         PrintUsageInfo(KNoteAlreadyRunning);
       
   191         }
       
   192     return KErrNone;
       
   193     }
       
   194 
       
   195 // --------------------------------------------------------------------------------------------
       
   196 static TInt EndProfilerProcess()
       
   197     {
       
   198     LOGTEXT(_L("EndProfilerProcess() ..."));
       
   199 
       
   200     // call profiler to stop sampling
       
   201     TInt err = RProfiler::StopSampling();
       
   202     
       
   203     // check if command succesfull
       
   204     if( err != KErrNone )
       
   205         {
       
   206         LOGTEXT(_L("Profiler: could not connect engine, stop failed"));
       
   207         return err;
       
   208         }
       
   209     
       
   210     // exit the profiler process
       
   211     err = RProfiler::ExitProfiler();
       
   212     // check if command succesfull
       
   213     if( err != KErrNone )
       
   214         {
       
   215         LOGTEXT(_L("Profiler: could not connect engine, exit failed"));
       
   216         return err;
       
   217         }
       
   218     
       
   219     return KErrNone;
       
   220     }
       
   221 
       
   222 // --------------------------------------------------------------------------------------------
       
   223 static TInt TestSettingsFile(const TDesC& configFile)
       
   224     {
       
   225     RFs fs;
       
   226     RFile file;
       
   227     TInt err(KErrNone);
       
   228 
       
   229     // check if file server can be connected
       
   230     if (fs.Connect() != KErrNone)
       
   231         {
       
   232         // file server couldn't be connected, return false
       
   233         return KErrNotFound;
       
   234         }
       
   235 
       
   236     // check if config file name length is > 0
       
   237     if (configFile.Length() > 0)
       
   238         {
       
   239         // open the file with the given path and name
       
   240         err = file.Open(fs,configFile,EFileRead);
       
   241         // check if file open was succesfull 
       
   242         if(err != KErrNone)
       
   243             {
       
   244             // return false if failed
       
   245             fs.Close();
       
   246             return err;
       
   247             }
       
   248         
       
   249         }
       
   250     else
       
   251         {
       
   252         // configFile length 0, return false
       
   253         fs.Close();
       
   254         return KErrNotFound;
       
   255         }
       
   256     // return true if tests passed
       
   257     file.Close();
       
   258     fs.Close();
       
   259     return KErrNone;
       
   260     }
       
   261 
       
   262 // --------------------------------------------------------------------------------------------
       
   263 static TInt ParseCommandAndExecute()
       
   264     {
       
   265     // commands literals for finding the right keyword 
       
   266     _LIT(KAutomatedTestStart,"start*");
       
   267     _LIT(KAutomatedTestEnd,"end*");
       
   268     _LIT(KAutomatedTestTimed,"timed*");
       
   269     _LIT(KBootMeasurement,"boot*");
       
   270     TBuf<256> c;
       
   271     TInt match(KErrNotFound);
       
   272     TInt bootmatch(KErrNotFound);
       
   273     TBool myBoot=false;
       
   274     // copy the full command line with arguments into a buffer
       
   275     User::CommandLine(c);
       
   276     LOGSTRING2("command: %S", &c);
       
   277 
       
   278     // try to match with each of the literals defined above
       
   279     // (commands in atf format)
       
   280     
       
   281     // check if command is "start"
       
   282     match = c.Match(KAutomatedTestStart);
       
   283     if (match != KErrNotFound)
       
   284         {
       
   285         LOGTEXT(_L("Found keyword start"));
       
   286 
       
   287         TBuf<256> fileName;
       
   288         fileName.Append(c.Right(c.Length()-6));
       
   289         LOGSTRING2("Filename is %S", &fileName);
       
   290         if(TestSettingsFile(fileName) != KErrNone)
       
   291             {
       
   292             _LIT(KSettingsFileFailed, "False settings file");
       
   293             PrintUsageInfo(KSettingsFileFailed);
       
   294             return -2;
       
   295             }
       
   296         // execute Profile process 
       
   297         if( StartProfilerProcess(fileName, 0, myBoot) == KErrNone )
       
   298             {
       
   299             return -10;
       
   300             }
       
   301         return -2;
       
   302         }
       
   303 
       
   304     // check if command is "end"
       
   305     match = c.Match(KAutomatedTestEnd);
       
   306     if (match != KErrNotFound)
       
   307         {
       
   308         LOGTEXT(_L("Found keyword end"));
       
   309 
       
   310         // stop the profiling process
       
   311         EndProfilerProcess();
       
   312         return -10;
       
   313         }
       
   314 
       
   315     // check if command is "timed"
       
   316     match = c.Match(KAutomatedTestTimed);
       
   317     // check if command is "boot"
       
   318     bootmatch = c.Match(KBootMeasurement);
       
   319     if ((match!= KErrNotFound) || (bootmatch != KErrNotFound))
       
   320         {
       
   321         // command "timed" or " boot" found, need for finding settings file and run time next
       
   322         if(bootmatch != KErrNotFound)
       
   323             {
       
   324             LOGTEXT(_L("Found keyword boot"));
       
   325             myBoot = TRUE;
       
   326             }
       
   327         if(match != KErrNotFound)
       
   328             {
       
   329             LOGTEXT(_L("Found keyword timed"));
       
   330             }
       
   331         
       
   332         TBuf<256> temp;
       
   333         temp.Append(c);
       
   334         TLex lex(temp);
       
   335         
       
   336         TBuf<256> fileName;
       
   337         TInt seconds;
       
   338 
       
   339         // parse the first command line argument, the command itself
       
   340         lex.Mark();
       
   341         lex.SkipCharacters();
       
   342         if(lex.TokenLength() != 0)
       
   343             {
       
   344             #ifdef PIPROFILER_PRINTS
       
   345             TPtrC token = lex.MarkedToken();
       
   346             LOGSTRING2("Token 1 %S",&token);
       
   347             #endif
       
   348             }
       
   349         else
       
   350             {
       
   351             LOGTEXT(_L("Problem 1 in parsing command line"));
       
   352             _LIT(KSettingsFileFailed, "Failure: False argument");
       
   353             PrintUsageInfo(KSettingsFileFailed);
       
   354             return -2;
       
   355             }
       
   356 
       
   357         // parse the second command line argument, the settings file name
       
   358         lex.SkipSpace();
       
   359         lex.Mark();
       
   360         lex.SkipCharacters();
       
   361         if(lex.TokenLength() != 0)
       
   362             {
       
   363             TPtrC token2 = lex.MarkedToken();
       
   364             LOGSTRING2("Token 2 %S",&token2);
       
   365             fileName.Append(token2);
       
   366             LOGSTRING2("Value of fileName is %S",&fileName);
       
   367 //            if(TestSettingsFile(fileName) != KErrNone)
       
   368 //                {
       
   369 //                _LIT(KSettingsFileFailed, "Failure: False settings file");
       
   370 //                PrintUsageInfo(KSettingsFileFailed);
       
   371 //                return -2;
       
   372 //                }
       
   373             }
       
   374         else
       
   375             {
       
   376             LOGTEXT(_L("Problem 2 in parsing command line"));
       
   377             _LIT(KSettingsFileFailed, "Failure: No settings file specified");
       
   378             PrintUsageInfo(KSettingsFileFailed);
       
   379             return -2;
       
   380             }
       
   381 
       
   382         // parse the third command line argument, the run time in seconds
       
   383         lex.SkipSpace();
       
   384         lex.Mark();
       
   385         lex.SkipCharacters();
       
   386         if(lex.TokenLength() != 0)
       
   387             {
       
   388             // third token ok, try to convert into TInt value
       
   389             TPtrC token3 = lex.MarkedToken();
       
   390             LOGSTRING2("Token 3 %S",&token3);
       
   391             TLex num(token3);
       
   392             TInt err = num.Val(seconds);
       
   393             // check if given time value acceptable 
       
   394             if (err != KErrNone)
       
   395                 {
       
   396                 // value parsing failed, show info note to user
       
   397                 _LIT(KSecondsFailed, "Failure: False time value");
       
   398                 PrintUsageInfo(KSecondsFailed);
       
   399                 return -2;
       
   400                 }
       
   401             }
       
   402         else
       
   403             {
       
   404             LOGTEXT(_L("Problem 3 in parsing command line"));
       
   405             _LIT(KSecondsFailed, "Failure: False time value");
       
   406             PrintUsageInfo(KSecondsFailed);
       
   407             return -2;
       
   408             }           
       
   409         
       
   410         LOGSTRING3("Filename is %S, seconds is %d", &fileName, seconds);
       
   411         // execute Profile process 
       
   412         if( StartProfilerProcess(fileName, seconds, myBoot) == KErrNone )
       
   413             {
       
   414             return -10;
       
   415             }
       
   416         return -2;
       
   417         }
       
   418     
       
   419     // check if space character in the middle of command line string 
       
   420     if( c.LocateReverse(' ') != KErrNotFound)
       
   421         {
       
   422         _LIT(KWrongParameters, "Failure: Check command line parameters");
       
   423         PrintUsageInfo(KWrongParameters);
       
   424         return -2;
       
   425         }
       
   426     
       
   427     // return -1 if no command found
       
   428     LOGTEXT(_L("No keyword found"));
       
   429     return -1;
       
   430     }
       
   431 
       
   432 // --------------------------------------------------------------------------------------------
       
   433 GLDEF_C TInt E32Main()
       
   434     {
       
   435     // parse command line arguments
       
   436     ParseCommandAndExecute();
       
   437 
       
   438     return KErrNone;
       
   439 
       
   440     }