1 2 package dot.junit; 3 4 5 import com.android.ddmlib.IDevice; 6 7 import java.io.File; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 import java.io.InputStream; 11 import java.io.UnsupportedEncodingException; 12 import java.util.Scanner; 13 14 public class DeviceUtil { 15 16 private static boolean DEBUG = System.getProperty("cts.vm-tests.debug") != null; 17 18 /** 19 * Executes the command and its arguments in a native process. 20 * 21 * @param commandAndArgs a string array to be passed containing the 22 * executable and its arguments 23 * @param okIndicator if not null, this String must occur in the stdout of 24 * the executable (since only checking for the return code is not 25 * sufficient e.g. for adb shell cmd) 26 * @throws Exception thrown by the underlying command in case of an error. 27 */ 28 public static void digestCommand(String[] commandAndArgs, String okIndicator) { 29 RuntimeException re = null; 30 try { 31 String c = ""; 32 for (int i = 0; i < commandAndArgs.length; i++) { 33 c += commandAndArgs[i] + " "; 34 } 35 if (DEBUG) System.out.print("com: " + c); 36 StringBuilder sb = new StringBuilder(); 37 ProcessBuilder pb = new ProcessBuilder(commandAndArgs).redirectErrorStream(true); 38 Process p = pb.start(); 39 40 InputStream is = p.getInputStream(); 41 Scanner scanner = new Scanner(is); 42 int retCode = p.waitFor(); 43 while (scanner.hasNextLine()) { 44 sb.append(scanner.nextLine()); 45 } 46 scanner.close(); 47 if (retCode != 0 || (okIndicator != null && !sb.toString().contains(okIndicator))) { 48 String msg = sb.toString() + "\nreturn code: " + retCode; 49 re = new RuntimeException(msg); 50 if (DEBUG) System.out.println("-> error! msg:"+msg); 51 } else { 52 if (DEBUG) System.out.println(" -> " + retCode); 53 } 54 } catch (Exception e) { 55 throw new RuntimeException("Exception occurred: " + e.getClass().getName() + ", msg:" 56 + e.getMessage()); 57 } finally { 58 if (re != null) { 59 throw re; 60 } 61 } 62 } 63 64 public static String createFilePath(String testName) throws IOException { 65 // e.g. /dot/junit/opcodes/add_double/d/T_add_double_1.jar 66 FileOutputStream fos = null; 67 InputStream is = null; 68 File f; 69 try { 70 is = DeviceUtil.class.getResourceAsStream("/tests/" + testName); 71 if (is == null) { 72 throw new RuntimeException("could not find resource /tests" + testName 73 + " in classpath"); 74 } 75 f = File.createTempFile("cts-adbpush-", ".jar"); 76 int len = 4096; 77 byte[] bytes = new byte[len]; 78 fos = new FileOutputStream(f); 79 int b; 80 while ((b = is.read(bytes)) > 0) { 81 fos.write(bytes, 0, b); 82 } 83 } finally { 84 if (is != null) { 85 is.close(); 86 } 87 if (fos != null) { 88 fos.close(); 89 } 90 } 91 return f.getAbsolutePath(); 92 } 93 94 public static void adbPush(IDevice device, String source, String target) 95 throws IOException { 96 String tmp_source = null; 97 try { 98 tmp_source = DeviceUtil.createFilePath(source); 99 DeviceUtil.digestCommand(new String[] {"adb", "-s", device.getSerialNumber(), "push", 100 tmp_source, target}, null); 101 } finally { 102 // Clean up local temp file after pushing it to device. 103 if (tmp_source != null) { 104 File f = new File(tmp_source); 105 if (f.exists()) { 106 f.delete(); 107 } 108 } 109 } 110 } 111 112 public static void adbExec(IDevice device, String classpath, String mainclass) { 113 DeviceUtil.digestCommand(new String[] {"adb", "-s", device.getSerialNumber(), "shell", 114 "mkdir", "/data/local/tmp/dalvik-cache"}, null); 115 DeviceUtil.digestCommand(new String[] {"adb", "-s", device.getSerialNumber(), "shell", 116 "ANDROID_DATA=/data/local/tmp", "dalvikvm", "-Xint:portable", "-Xmx512M", "-Xss32K", 117 "-Djava.io.tmpdir=/data/local/tmp", "-classpath", classpath, mainclass, "&&", 118 "echo", "mk_dalvikvmok" }, "mk_dalvikvmok"); 119 } 120 } 121