sysanadatacapture/piprofiler/piprofiler/engine/src/ProfilerEshell.cpp
changeset 1 3ff3fecb12fe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysanadatacapture/piprofiler/piprofiler/engine/src/ProfilerEshell.cpp	Thu Feb 11 15:52:57 2010 +0200
@@ -0,0 +1,419 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#include <f32file.h>
+#include <e32cons.h>
+
+#include "ProfilerEshell.h"
+#include <piprofiler/ProfilerSession.h>
+
+
+
+_LIT(KProfilerEngineExe, "PIProfilerEngine.exe");
+
+/*
+ *
+ * Static methods for controlling the profiler
+ * through command line
+ *
+ */
+// --------------------------------------------------------------------------------------------
+static void PrintUsageInfo(const TDesC& aAdditionalInfo)
+    {
+    _LIT(KConsoleName, "Console");
+    _LIT(KLegalNote, "PIProfiler Version 2.00.0 Copyright @ 2009 Nokia\n");
+    _LIT(KUsageNote, "Usage: PIProfiler [start/end/timed] settingsfile [time to run]\n");
+    _LIT(KExample, "Example: PIProfiler timed C:\\data\\piprofilersettings.txt 60\n");
+
+    TRAP_IGNORE(CConsoleBase* console = Console::NewL(KConsoleName,TSize(KConsFullScreen,KConsFullScreen));
+        console->Printf(KLegalNote);
+        console->Printf(KUsageNote);
+        console->Printf(KExample);
+        console->Write(aAdditionalInfo);
+    
+        console->Printf(_L("\n[Press any key]"));
+        console->Getch();
+        delete console;);
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt FindProcess()
+    {
+    TFindProcess procName;
+    procName.Find(_L("PIProfilerEngine.exe*"));
+    TFullName aResult;
+    
+    // find the first appearance, i.e. "myself"...
+    TInt err(procName.Next(aResult));  // the first appearance
+    if(err == KErrNotFound)
+        {
+        // now check if old Profiler is still running on
+        procName.Find(_L("BappeaProf.exe*"));
+        err = procName.Next(aResult);
+        // check if old profiler process found 
+        if(err == KErrNone)
+            {
+            // return error for error handling
+            return KErrAlreadyExists;
+            }
+        // return KErrNotFound and a new profiler engine process can be started
+        return KErrNotFound;
+        }
+    return err;
+    }
+
+/**
+ * Function for starting profiler engine in the background,
+ * call profiler to load settings
+ * and start sampling process
+ * 
+ * @param configFile name and location of settings file
+ */
+// --------------------------------------------------------------------------------------------
+static TInt StartProfilerProcess(const TDesC& configFile, TInt aRunTimeInSeconds)
+    {
+    TInt err(KErrNone);
+    RProcess proc;
+    TRequestStatus status = KRequestPending;
+    
+    // check if process exists
+    err = FindProcess();
+    LOGSTRING2(_L("PIProfiler: tried to find process, response %d"), err); 
+
+    // check if already exists and don't start a new eshell profiling
+    if( err == KErrNotFound )
+        {
+        // try create new process
+        err = proc.Create(KProfilerEngineExe, configFile);
+
+        LOGSTRING2(_L("PIProfiler: created process, response %d"), err); 
+
+        // check if RProcess::Create() succeeded
+        if( err == KErrNone )
+            {
+            // kick off the engine process
+            proc.Resume();
+            
+            // wait for the constructor to complete 
+            proc.Rendezvous(status); // Trigger rendezvous on the supplied TRequestStatus object
+            User::WaitForRequest(status); 
+            
+            // just lose the handle
+            proc.Close();
+    
+            // check if command succesfull
+            if( err != KErrNone )
+                {
+                LOGTEXT(_L("Profiler: could not connect engine"));
+                return err;
+                }
+            
+            // start sampling, using settings found in settings file or if not found the default settings
+            err = RProfiler::StartSampling();
+            // check if command succesful
+            if( err != KErrNone )
+                {
+                _LIT(KNoteProfilerCannotStart, "PI Profiler: cannot start PI Profiler, check settings!");
+                PrintUsageInfo(KNoteProfilerCannotStart);
+                // check if process still alive
+                if(err != KErrNotFound)
+                    {
+                    // exit the profiler process since process was started
+                    RProfiler::ExitProfiler();
+                    }
+                return err;
+                }
+            
+            if(aRunTimeInSeconds > 0)
+                {
+                RDebug::Print(_L("Profiler running for %d s... "), aRunTimeInSeconds);
+                User::After(aRunTimeInSeconds*1000000);
+                RDebug::Print(_L("************* Profiler process closing *********"));
+        
+                // stop sampling process
+                err = RProfiler::StopSampling();
+                // check if command succesfull
+                if( err != KErrNone )
+                    {
+                    LOGTEXT(_L("Profiler: could not connect engine, stop failed"));
+                    return err;
+                    }
+                
+                // exit the profiler process
+                err = RProfiler::ExitProfiler();
+                // check if command succesfull
+                if( err != KErrNone )
+                    {
+                    LOGTEXT(_L("Profiler: could not connect engine, exit failed"));
+                    return err;
+                    }
+                }
+            } 
+        else
+            {
+            _LIT(KNoteCannotFindProfiler, "PI Profiler: could not find PIProfilerEngine.exe");
+            PrintUsageInfo(KNoteCannotFindProfiler);
+            }
+        }
+    // check if old Profiler is already running
+    else if( err == KErrAlreadyExists )
+        {
+        _LIT(KNoteAlreadyRunning, "PI Profiler: old Profiler process already running, close it down before launching the new!");
+        PrintUsageInfo(KNoteAlreadyRunning);
+        }
+    // otherwise show error note
+    else
+        {
+        _LIT(KNoteAlreadyRunning, "PI Profiler: already running, not able to launch new one. NOTE: check if UI running!");
+        PrintUsageInfo(KNoteAlreadyRunning);
+        }
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt EndProfilerProcess()
+    {
+    LOGTEXT(_L("EndProfilerProcess() ..."));
+
+    // call profiler to stop sampling
+    TInt err = RProfiler::StopSampling();
+    
+    // check if command succesfull
+    if( err != KErrNone )
+        {
+        LOGTEXT(_L("Profiler: could not connect engine, stop failed"));
+        return err;
+        }
+    
+    // exit the profiler process
+    err = RProfiler::ExitProfiler();
+    // check if command succesfull
+    if( err != KErrNone )
+        {
+        LOGTEXT(_L("Profiler: could not connect engine, exit failed"));
+        return err;
+        }
+    
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt TestSettingsFile(const TDesC& configFile)
+    {
+    RFs fs;
+    RFile file;
+    TInt err(KErrNone);
+
+    // check if file server can be connected
+    if (fs.Connect() != KErrNone)
+        {
+        // file server couldn't be connected, return false
+        return KErrNotFound;
+        }
+
+    // check if config file name length is > 0
+    if (configFile.Length() > 0)
+        {
+        // open the file with the given path and name
+        err = file.Open(fs,configFile,EFileRead);
+        // check if file open was succesfull 
+        if(err != KErrNone)
+            {
+            // return false if failed
+            fs.Close();
+            return err;
+            }
+        
+        }
+    else
+        {
+        // configFile length 0, return false
+        fs.Close();
+        return KErrNotFound;
+        }
+    // return true if tests passed
+    file.Close();
+    fs.Close();
+    return KErrNone;
+    }
+
+// --------------------------------------------------------------------------------------------
+static TInt ParseCommandAndExecute()
+    {
+    // commands literals for finding the right keyword 
+    _LIT(KAutomatedTestStart,"start*");
+    _LIT(KAutomatedTestEnd,"end*");
+    _LIT(KAutomatedTestTimed,"timed*");
+    
+    TBuf<256> c;
+    TInt match(KErrNotFound);
+    
+    // copy the full command line with arguments into a buffer
+    User::CommandLine(c);
+
+    // try to match with each of the literals defined above
+    // (commands in atf format)
+
+    // check if command is "start"
+    match = c.Match(KAutomatedTestStart);
+    if (match != KErrNotFound)
+        {
+        LOGTEXT(_L("Found keyword start"));
+
+        TBuf<256> fileName;
+        fileName.Append(c.Right(c.Length()-6));
+        LOGSTRING2(_L("Filename is %S"), &fileName);
+        if(TestSettingsFile(fileName) != KErrNone)
+            {
+            _LIT(KSettingsFileFailed, "False settings file");
+            PrintUsageInfo(KSettingsFileFailed);
+            return -2;
+            }
+        // execute Profile process 
+        if( StartProfilerProcess(fileName, 0) == KErrNone )
+            {
+            return -10;
+            }
+        return -2;
+        }
+
+    // check if command is "end"
+    match = c.Match(KAutomatedTestEnd);
+    if (match != KErrNotFound)
+        {
+        LOGTEXT(_L("Found keyword end"));
+
+        // stop the profiling process
+        EndProfilerProcess();
+        return -10;
+        }
+
+    // check if command is "timed"
+    match = c.Match(KAutomatedTestTimed);
+    if (match != KErrNotFound)
+        {
+        // command "timed" found, need for finding settings file and run time next
+        LOGTEXT(_L("Found keyword timed"));
+        TBuf<256> temp;
+        temp.Append(c);
+        TLex lex(temp);
+        
+        TBuf<256> fileName;
+        TInt seconds;
+
+        // parse the first command line argument, the command itself
+        lex.Mark();
+        lex.SkipCharacters();
+        if(lex.TokenLength() != 0)
+            {
+            #ifdef PIPROFILER_PRINTS
+            TPtrC token = lex.MarkedToken();
+            LOGSTRING2("Token 1 %S",&token);
+            #endif
+            }
+        else
+            {
+            LOGTEXT(_L("Problem 1 in parsing command line"));
+            _LIT(KSettingsFileFailed, "Failure: False argument");
+            PrintUsageInfo(KSettingsFileFailed);
+            return -2;
+            }
+
+        // parse the second command line argument, the settings file name
+        lex.SkipSpace();
+        lex.Mark();
+        lex.SkipCharacters();
+        if(lex.TokenLength() != 0)
+            {
+            TPtrC token2 = lex.MarkedToken();
+            LOGSTRING2(_L("Token 2 %S"),&token2);
+            fileName.Append(token2);
+            LOGSTRING2(_L("Value of fileName is %S"),&fileName);
+//            if(TestSettingsFile(fileName) != KErrNone)
+//                {
+//                _LIT(KSettingsFileFailed, "Failure: False settings file");
+//                PrintUsageInfo(KSettingsFileFailed);
+//                return -2;
+//                }
+            }
+        else
+            {
+            LOGTEXT(_L("Problem 2 in parsing command line"));
+            _LIT(KSettingsFileFailed, "Failure: No settings file specified");
+            PrintUsageInfo(KSettingsFileFailed);
+            return -2;
+            }
+
+        // parse the third command line argument, the run time in seconds
+        lex.SkipSpace();
+        lex.Mark();
+        lex.SkipCharacters();
+        if(lex.TokenLength() != 0)
+            {
+            // third token ok, try to convert into TInt value
+            TPtrC token3 = lex.MarkedToken();
+            LOGSTRING2(_L("Token 3 %S"),&token3);
+            TLex num(token3);
+            TInt err = num.Val(seconds);
+            // check if given time value acceptable 
+            if (err != KErrNone)
+                {
+                // value parsing failed, show info note to user
+                _LIT(KSecondsFailed, "Failure: False time value");
+                PrintUsageInfo(KSecondsFailed);
+                return -2;
+                }
+            }
+        else
+            {
+            LOGTEXT(_L("Problem 3 in parsing command line"));
+            _LIT(KSecondsFailed, "Failure: False time value");
+            PrintUsageInfo(KSecondsFailed);
+            return -2;
+            }           
+        
+        LOGSTRING3(_L("Filename is %S, seconds is %d"), &fileName, seconds);
+        // execute Profile process 
+        if( StartProfilerProcess(fileName, seconds) == KErrNone )
+            {
+            return -10;
+            }
+        return -2;
+        }
+    
+    // check if space character in the middle of command line string 
+    if( c.LocateReverse(' ') != KErrNotFound)
+        {
+        _LIT(KWrongParameters, "Failure: Check command line parameters");
+        PrintUsageInfo(KWrongParameters);
+        return -2;
+        }
+    
+    // return -1 if no command found
+    LOGTEXT(_L("No keyword found"));
+    return -1;
+    }
+
+// --------------------------------------------------------------------------------------------
+GLDEF_C TInt E32Main()
+    {
+    // parse command line arguments
+    ParseCommandAndExecute();
+
+    return KErrNone;
+
+    }