1515
1616package com .arm .wa .uiauto .applaunch ;
1717
18+ import android .os .Build ;
1819import android .os .Bundle ;
20+ import android .os .ParcelFileDescriptor ;
1921import android .support .test .runner .AndroidJUnit4 ;
2022import android .support .test .uiautomator .UiObject ;
2123import android .util .Log ;
3032import org .junit .Test ;
3133import org .junit .runner .RunWith ;
3234
35+ import java .io .BufferedReader ;
36+ import java .io .IOException ;
3337import java .io .File ;
38+ import java .io .InputStreamReader ;
3439
3540import dalvik .system .DexClassLoader ;
3641
@@ -52,18 +57,19 @@ public class UiAutomation extends BaseUiAutomation {
5257 protected Bundle parameters ;
5358 protected String packageName ;
5459 protected String packageID ;
60+ protected boolean suHasCommandOption ;
5561
5662 @ Before
5763 public void initialize () throws Exception {
5864 parameters = getParams ();
5965 packageID = getPackageID (parameters );
6066
67+ suHasCommandOption = parameters .getBoolean ("su_has_command_option" );
68+
6169 // Get workload apk file parameters
62- String packageName = parameters .getString ("package_name" );
70+ packageName = parameters .getString ("package_name" );
6371 String workload = parameters .getString ("workload" );
64- String workloadAPKPath = parameters .getString ("workdir" );
65- String workloadName = String .format ("com.arm.wa.uiauto.%1s.apk" , workload );
66- String workloadAPKFile = String .format ("%1s/%2s" , workloadAPKPath , workloadName );
72+ String workloadAPKFile = parameters .getString ("workload_apk" );
6773
6874 // Load the apk file
6975 File apkFile = new File (workloadAPKFile );
@@ -153,7 +159,6 @@ private class AppLaunch {
153159 private String testTag ;
154160 private String launchCommand ;
155161 private ActionLogger logger ;
156- Process launch_p ;
157162
158163 public AppLaunch (String testTag , String launchCommand ) {
159164 this .testTag = testTag ;
@@ -169,24 +174,13 @@ public void startLaunch() throws Exception{
169174
170175 // Launches the application.
171176 public void launchMain () throws Exception {
172- launch_p = Runtime .getRuntime ().exec (launchCommand );
173- launchValidate (launch_p );
174- }
175-
176- // Called by launchMain() to check if app launch is successful
177- public void launchValidate (Process launch_p ) throws Exception {
178- launch_p .waitFor ();
179- Integer exit_val = launch_p .exitValue ();
180- if (exit_val != 0 ) {
181- throw new Exception ("Application could not be launched" );
182- }
177+ executeShellCommand (launchCommand );
183178 }
184179
185180 // Marks the end of application launch of the workload.
186181 public void endLaunch () throws Exception {
187182 waitObject (launchEndObject , launch_timeout );
188183 logger .stop ();
189- launch_p .destroy ();
190184 }
191185 }
192186
@@ -203,15 +197,14 @@ else if(applaunchType.equals("launch_from_long-idle")) {
203197
204198 // Kills the application process
205199 public void killApplication () throws Exception {
206- Process kill_p ;
207200 String command = String .format ("am force-stop %s" , packageName );
208- kill_p = Runtime .getRuntime ().exec (new String [] { "su" , "-c" , command });
209- kill_p .waitFor ();
210- kill_p .destroy ();
201+ executeShellCommand (command );
211202 }
212203
213204 // Kills the background processes
214205 public void killBackground () throws Exception {
206+ // Workload has KILL_BACKGROUND_PROCESSES permission so it can execute following
207+ // command and it is not necessary to execute it with shell permissions.
215208 Process kill_p ;
216209 kill_p = Runtime .getRuntime ().exec ("am kill-all" );
217210 kill_p .waitFor ();
@@ -220,15 +213,80 @@ public void killBackground() throws Exception{
220213
221214 // Drop the caches
222215 public void dropCaches () throws Exception {
223- Process sync ;
224- sync = Runtime .getRuntime ().exec (new String [] { "su" , "-c" , "sync" });
225- sync .waitFor ();
226- sync .destroy ();
227-
228- Process drop_cache ;
229- String command = "echo 3 > /proc/sys/vm/drop_caches" ;
230- drop_cache = Runtime .getRuntime ().exec (new String [] { "su" , "-c" , command });
231- drop_cache .waitFor ();
232- drop_cache .destroy ();
216+ executeShellCommand ("sync" , /*asRoot=*/ true );
217+ executeShellCommand ("echo 3 > /proc/sys/vm/drop_caches" , /*asRoot=*/ true );
218+ }
219+
220+ private String getSuCommand (String command ) {
221+ if (suHasCommandOption ) {
222+ return String .format ("su -c '%s'" , command );
223+ }
224+ // If su doesn't support -c argument we assume that it has following usage:
225+ // su [WHO [COMMAND]]
226+ // that corresponds to su from engineering Android version.
227+ return String .format ("su root %s" , command );
228+ }
229+
230+ private void executeShellCommand (String command ) throws Exception {
231+ executeShellCommand (command , /*asRoot=*/ false );
232+ }
233+
234+ private static ParcelFileDescriptor [] executeShellCommand (android .app .UiAutomation uiAutomation ,
235+ String command ) throws IOException {
236+ ParcelFileDescriptor [] result = new ParcelFileDescriptor [2 ];
237+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .UPSIDE_DOWN_CAKE ) {
238+ ParcelFileDescriptor [] fds = uiAutomation .executeShellCommandRwe (command );
239+ fds [1 ].close (); // close stdin
240+ result [0 ] = fds [0 ]; // stdout
241+ result [1 ] = fds [2 ]; // stderr
242+ return result ;
243+ }
244+
245+ result [0 ] = uiAutomation .executeShellCommand (command );
246+ return result ;
247+ }
248+
249+ private void executeShellCommand (String command , boolean asRoot ) throws Exception {
250+ android .app .UiAutomation uiAutomation = mInstrumentation .getUiAutomation ();
251+
252+ String shellCommand = command ;
253+ if (asRoot ) {
254+ shellCommand = getSuCommand (command );
255+ }
256+
257+ Log .d ("Shell command: " , shellCommand );
258+ ParcelFileDescriptor [] fds = UiAutomation .executeShellCommand (uiAutomation , command );
259+ ParcelFileDescriptor fdOut = fds [0 ];
260+ ParcelFileDescriptor fdErr = fds [1 ];
261+
262+ String out = readStreamAndClose (fdOut );
263+ Log .d ("Shell out: " , out );
264+
265+ String err = readStreamAndClose (fdErr );
266+ if (!err .isEmpty ()) {
267+ Log .e ("Shell err: " , err );
268+ String msg = String .format ("Shell command '%s' failed with error: '%s'" , command , err );
269+ throw new Exception (msg );
270+ }
271+ }
272+
273+ private static String readStreamAndClose (ParcelFileDescriptor fd ) throws IOException {
274+ if (fd == null ) {
275+ return "" ;
276+ }
277+
278+ try (BufferedReader in = new BufferedReader (new InputStreamReader (
279+ new ParcelFileDescriptor .AutoCloseInputStream (fd )))) {
280+ StringBuilder sb = new StringBuilder ();
281+ while (true ) {
282+ String line = in .readLine ();
283+ if (line == null ) {
284+ break ;
285+ }
286+ sb .append (line );
287+ sb .append ('\n' );
288+ }
289+ return sb .toString ();
290+ }
233291 }
234292}
0 commit comments