debugsrv/runmodedebug/tsrc/rm_debug/common/t_target_launcher.cpp
changeset 56 aa2539c91954
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/debugsrv/runmodedebug/tsrc/rm_debug/common/t_target_launcher.cpp	Fri Oct 08 14:56:39 2010 +0300
@@ -0,0 +1,224 @@
+// Copyright (c) 2007-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:
+// Helper app to launch debug targets. Uses command-line parameters as follows using a + sign:
+//  +n<number of applications to launch>
+//  +m<number of times to launch each application>
+//  +o<order of launch, 1 means launch in reverse order>
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32ldr.h>
+#include <e32cmn.h>
+#include <e32cmn_private.h>
+#include <f32dbg.h>
+#include <f32file.h>
+#include <hal.h>
+#include <u32hal.h>
+#include <e32property.h>
+
+#include "t_target_launcher.h"
+
+
+/**
+  Launch a process
+
+  @param aProcess The RProcess object to use to create the process
+  @param aExeName File name of the executable to create the process from
+  @param aCommandLine The command line to pass to the new process
+  @return KErrNone on success, or one of the other system wide error codes
+  */
+TInt LaunchProcess(RProcess& aProcess, TDesC & aExeName, TPtr & aCommandLine )
+    {
+
+    TPtrC commandLine( aCommandLine );
+
+    TInt err = aProcess.Create( aExeName, commandLine );
+
+    // check that there was no error raised
+    if(err != KErrNone)
+        {
+        return err;
+        }
+
+    TRequestStatus status = KRequestPending;
+    aProcess.Rendezvous(status);
+
+    if(KRequestPending != status.Int())
+        {
+        // startup failed so kill the process
+        RDebug::Printf( "> RProcess Rendezvous() failed with %d. Killing process", status.Int() );
+        aProcess.Kill(KErrNone);
+        return status.Int();
+        }
+    else
+        {
+        // start up succeeded so resume the process
+        aProcess.Resume();
+        User::WaitForRequest(status);
+        if(KErrNone != status.Int())
+            {
+            RDebug::Printf( "> RProcess Resume() failed with %d. Killing process", status.Int() );
+            aProcess.Kill(KErrNone);
+            }
+        return status.Int();
+        }
+    }
+
+/**
+ * Read command line parameters and control the launching of targets. 
+ * Create global launch semaphore KLaunchSemaphoreName
+ */
+void MainL()
+    {
+
+    TInt numApps = KNumApps;
+    TInt numLaunches = KNumLaunches;
+    TInt launchControl = 0;
+
+    TInt argc = User::CommandLineLength();
+    HBufC* commandLine = NULL;
+    RDebug::Printf( ">Launcher Process() argc=%d", argc );
+
+    if( argc )
+        {
+        commandLine = HBufC::NewLC(argc);
+        TPtr commandLineBuffer = commandLine->Des();
+        User::CommandLine(commandLineBuffer);
+
+        RBuf printCommandLine;
+        CleanupClosePushL( printCommandLine );
+        printCommandLine.CreateL( commandLine->Des().Length() );
+        printCommandLine.Copy( commandLine->Des() );
+        printCommandLine.Collapse();
+        RDebug::Printf( ">command line = %S", &printCommandLine );
+        CleanupStack::PopAndDestroy( &printCommandLine );
+
+        // create a lexer and read through the command line
+        TLex lex(*commandLine);
+        while (!lex.Eos())
+            {
+            // only look for options with first character '+', other switches are for the targets
+            if (lex.Get() == '+')
+                {
+                TChar arg = lex.Get();
+                switch (arg)
+                    {
+                    case 'n':
+                        lex.Val( numApps );
+                        RDebug::Printf("parsed numApps as %d", numApps);
+                        break;
+                    case 'm':
+                        lex.Val( numLaunches );
+                        RDebug::Printf("parsed numLaunches as %d", numLaunches );
+                        break;
+                    case 'o':
+                        lex.Val( launchControl );
+                        RDebug::Printf("parsed launchControl as %d", launchControl);
+                        break;
+                    default:
+                        // unknown argument ignore it
+                        break;             
+                    }//switch
+                }// if +
+            }//while
+        }//if argc
+
+   RSemaphore launchSemaphore;
+   TInt ret = KErrNone;
+   CleanupClosePushL( launchSemaphore );
+   ret = launchSemaphore.CreateGlobal( KLaunchSemaphoreName, 0 );
+   RDebug::Printf( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret);
+   User::LeaveIfError( ret );
+
+   ret = launchSemaphore.OpenGlobal( KLaunchSemaphoreName );
+   RDebug::Printf( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret);
+   User::LeaveIfError( ret );
+   
+   //Only now indicate to the launcher that we have fully started, so they can find and open the semaphore
+   RProcess::Rendezvous(KErrNone);
+
+   //Now launch the requested number of apps for the requested number of launches
+   for( ; numLaunches > 0; numLaunches-- )
+       { 
+       for( TInt launchIndex = numApps; launchIndex > 0; launchIndex-- )  
+           {
+           RDebug::Printf( ">Target Launcher:  Semaphore wait app %d, launch %d", launchIndex, numLaunches );
+           launchSemaphore.Wait();
+
+           RBuf targetName;
+           CleanupClosePushL( targetName );
+           RDebug::Printf( ">Target Launcher:  targetName.Create %d, launch %d", launchIndex, numLaunches );
+           targetName.Create( KTargetExe().Length() + 2 );
+
+           if( launchControl == 1 )
+               {
+               // Reverse the order of the apps launched by reversing the index in the name
+               RDebug::Printf( ">Target Launcher:  targetName.Format %d, launch %d", numApps - launchIndex + 1, numLaunches );
+               targetName.Format( KTargetExe(), numApps - launchIndex + 1 );
+               }
+           else
+               {
+               RDebug::Printf( ">Target Launcher:  targetName.Format %d, launch %d", launchIndex, numLaunches );
+               targetName.Format( KTargetExe(), launchIndex );
+               }
+
+           RProcess aProc;
+           CleanupClosePushL( aProc ); 
+    
+           RDebug::Printf( ">Target Launcher: LaunchProcess %d, launch %d", launchIndex, numLaunches );
+           RDebug::Printf( ">LaunchProcess %lS", &targetName );
+           TPtr cmdLinePtr( commandLine->Des() );
+           ret = LaunchProcess( aProc, targetName, cmdLinePtr );
+           CleanupStack::PopAndDestroy( &aProc );
+
+           RDebug::Printf( "<Target Launcher: LaunchProcess returned %d", ret );
+           CleanupStack::PopAndDestroy( &targetName );
+
+           User::LeaveIfError( ret );
+
+           //By now the add proc event should have been delivered to the
+           //test app agent.
+           }
+       }
+
+    launchSemaphore.Wait( 500000 );
+
+    CleanupStack::PopAndDestroy( &launchSemaphore );
+
+    if( commandLine )
+       CleanupStack::PopAndDestroy( commandLine );
+ 
+    }
+
+
+GLDEF_C TInt E32Main()
+	{
+	RProcess thisProcess;
+	thisProcess.Rendezvous(KErrNone);
+	RDebug::Printf( ">Launcher Process()" );
+
+	CTrapCleanup* trap = CTrapCleanup::New();
+	if (!trap)
+		return KErrNoMemory;
+
+	TRAPD(err, MainL());
+	RDebug::Printf( "< Target launching returned %d", err);
+	
+	delete trap;
+	
+	return err;
+	}