|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Helper app to launch debug targets. Uses command-line parameters as follows using a + sign: |
|
15 // +n<number of applications to launch> |
|
16 // +m<number of times to launch each application> |
|
17 // +o<order of launch, 1 means launch in reverse order> |
|
18 // |
|
19 |
|
20 #include <e32base.h> |
|
21 #include <e32base_private.h> |
|
22 #include <e32cons.h> |
|
23 #include <e32test.h> |
|
24 #include <e32ldr.h> |
|
25 #include <e32cmn.h> |
|
26 #include <e32cmn_private.h> |
|
27 #include <f32dbg.h> |
|
28 #include <f32file.h> |
|
29 #include <hal.h> |
|
30 #include <u32hal.h> |
|
31 #include <e32property.h> |
|
32 |
|
33 #include "t_target_launcher.h" |
|
34 |
|
35 |
|
36 /** |
|
37 Launch a process |
|
38 |
|
39 @param aProcess The RProcess object to use to create the process |
|
40 @param aExeName File name of the executable to create the process from |
|
41 @param aCommandLine The command line to pass to the new process |
|
42 @return KErrNone on success, or one of the other system wide error codes |
|
43 */ |
|
44 TInt LaunchProcess(RProcess& aProcess, TDesC & aExeName, TPtr & aCommandLine ) |
|
45 { |
|
46 |
|
47 TPtrC commandLine( aCommandLine ); |
|
48 |
|
49 TInt err = aProcess.Create( aExeName, commandLine ); |
|
50 |
|
51 // check that there was no error raised |
|
52 if(err != KErrNone) |
|
53 { |
|
54 return err; |
|
55 } |
|
56 |
|
57 TRequestStatus status = KRequestPending; |
|
58 aProcess.Rendezvous(status); |
|
59 |
|
60 if(KRequestPending != status.Int()) |
|
61 { |
|
62 // startup failed so kill the process |
|
63 RDebug::Printf( "> RProcess Rendezvous() failed with %d. Killing process", status.Int() ); |
|
64 aProcess.Kill(KErrNone); |
|
65 return status.Int(); |
|
66 } |
|
67 else |
|
68 { |
|
69 // start up succeeded so resume the process |
|
70 aProcess.Resume(); |
|
71 User::WaitForRequest(status); |
|
72 if(KErrNone != status.Int()) |
|
73 { |
|
74 RDebug::Printf( "> RProcess Resume() failed with %d. Killing process", status.Int() ); |
|
75 aProcess.Kill(KErrNone); |
|
76 } |
|
77 return status.Int(); |
|
78 } |
|
79 } |
|
80 |
|
81 /** |
|
82 * Read command line parameters and control the launching of targets. |
|
83 * Create global launch semaphore KLaunchSemaphoreName |
|
84 */ |
|
85 void MainL() |
|
86 { |
|
87 |
|
88 TInt numApps = KNumApps; |
|
89 TInt numLaunches = KNumLaunches; |
|
90 TInt launchControl = 0; |
|
91 |
|
92 TInt argc = User::CommandLineLength(); |
|
93 HBufC* commandLine = NULL; |
|
94 RDebug::Printf( ">Launcher Process() argc=%d", argc ); |
|
95 |
|
96 if( argc ) |
|
97 { |
|
98 commandLine = HBufC::NewLC(argc); |
|
99 TPtr commandLineBuffer = commandLine->Des(); |
|
100 User::CommandLine(commandLineBuffer); |
|
101 |
|
102 RBuf printCommandLine; |
|
103 CleanupClosePushL( printCommandLine ); |
|
104 printCommandLine.CreateL( commandLine->Des().Length() ); |
|
105 printCommandLine.Copy( commandLine->Des() ); |
|
106 printCommandLine.Collapse(); |
|
107 RDebug::Printf( ">command line = %S", &printCommandLine ); |
|
108 CleanupStack::PopAndDestroy( &printCommandLine ); |
|
109 |
|
110 // create a lexer and read through the command line |
|
111 TLex lex(*commandLine); |
|
112 while (!lex.Eos()) |
|
113 { |
|
114 // only look for options with first character '+', other switches are for the targets |
|
115 if (lex.Get() == '+') |
|
116 { |
|
117 TChar arg = lex.Get(); |
|
118 switch (arg) |
|
119 { |
|
120 case 'n': |
|
121 lex.Val( numApps ); |
|
122 RDebug::Printf("parsed numApps as %d", numApps); |
|
123 break; |
|
124 case 'm': |
|
125 lex.Val( numLaunches ); |
|
126 RDebug::Printf("parsed numLaunches as %d", numLaunches ); |
|
127 break; |
|
128 case 'o': |
|
129 lex.Val( launchControl ); |
|
130 RDebug::Printf("parsed launchControl as %d", launchControl); |
|
131 break; |
|
132 default: |
|
133 // unknown argument ignore it |
|
134 break; |
|
135 }//switch |
|
136 }// if + |
|
137 }//while |
|
138 }//if argc |
|
139 |
|
140 RSemaphore launchSemaphore; |
|
141 TInt ret = KErrNone; |
|
142 CleanupClosePushL( launchSemaphore ); |
|
143 ret = launchSemaphore.CreateGlobal( KLaunchSemaphoreName, 0 ); |
|
144 RDebug::Printf( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret); |
|
145 User::LeaveIfError( ret ); |
|
146 |
|
147 ret = launchSemaphore.OpenGlobal( KLaunchSemaphoreName ); |
|
148 RDebug::Printf( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret); |
|
149 User::LeaveIfError( ret ); |
|
150 |
|
151 //Only now indicate to the launcher that we have fully started, so they can find and open the semaphore |
|
152 RProcess::Rendezvous(KErrNone); |
|
153 |
|
154 //Now launch the requested number of apps for the requested number of launches |
|
155 for( ; numLaunches > 0; numLaunches-- ) |
|
156 { |
|
157 for( TInt launchIndex = numApps; launchIndex > 0; launchIndex-- ) |
|
158 { |
|
159 RDebug::Printf( ">Target Launcher: Semaphore wait app %d, launch %d", launchIndex, numLaunches ); |
|
160 launchSemaphore.Wait(); |
|
161 |
|
162 RBuf targetName; |
|
163 CleanupClosePushL( targetName ); |
|
164 RDebug::Printf( ">Target Launcher: targetName.Create %d, launch %d", launchIndex, numLaunches ); |
|
165 targetName.Create( KTargetExe().Length() + 2 ); |
|
166 |
|
167 if( launchControl == 1 ) |
|
168 { |
|
169 // Reverse the order of the apps launched by reversing the index in the name |
|
170 RDebug::Printf( ">Target Launcher: targetName.Format %d, launch %d", numApps - launchIndex + 1, numLaunches ); |
|
171 targetName.Format( KTargetExe(), numApps - launchIndex + 1 ); |
|
172 } |
|
173 else |
|
174 { |
|
175 RDebug::Printf( ">Target Launcher: targetName.Format %d, launch %d", launchIndex, numLaunches ); |
|
176 targetName.Format( KTargetExe(), launchIndex ); |
|
177 } |
|
178 |
|
179 RProcess aProc; |
|
180 CleanupClosePushL( aProc ); |
|
181 |
|
182 RDebug::Printf( ">Target Launcher: LaunchProcess %d, launch %d", launchIndex, numLaunches ); |
|
183 RDebug::Printf( ">LaunchProcess %lS", &targetName ); |
|
184 TPtr cmdLinePtr( commandLine->Des() ); |
|
185 ret = LaunchProcess( aProc, targetName, cmdLinePtr ); |
|
186 CleanupStack::PopAndDestroy( &aProc ); |
|
187 |
|
188 RDebug::Printf( "<Target Launcher: LaunchProcess returned %d", ret ); |
|
189 CleanupStack::PopAndDestroy( &targetName ); |
|
190 |
|
191 User::LeaveIfError( ret ); |
|
192 |
|
193 //By now the add proc event should have been delivered to the |
|
194 //test app agent. |
|
195 } |
|
196 } |
|
197 |
|
198 launchSemaphore.Wait( 500000 ); |
|
199 |
|
200 CleanupStack::PopAndDestroy( &launchSemaphore ); |
|
201 |
|
202 if( commandLine ) |
|
203 CleanupStack::PopAndDestroy( commandLine ); |
|
204 |
|
205 } |
|
206 |
|
207 |
|
208 GLDEF_C TInt E32Main() |
|
209 { |
|
210 RProcess thisProcess; |
|
211 thisProcess.Rendezvous(KErrNone); |
|
212 RDebug::Printf( ">Launcher Process()" ); |
|
213 |
|
214 CTrapCleanup* trap = CTrapCleanup::New(); |
|
215 if (!trap) |
|
216 return KErrNoMemory; |
|
217 |
|
218 TRAPD(err, MainL()); |
|
219 RDebug::Printf( "< Target launching returned %d", err); |
|
220 |
|
221 delete trap; |
|
222 |
|
223 return err; |
|
224 } |