package com.android.tests.basic.buildscript; import com.android.annotations.NonNull; import com.android.builder.testing.api.DeviceConfig; import com.android.builder.testing.api.DeviceConnector; import com.android.builder.testing.api.DeviceException; import com.android.ddmlib.AdbCommandRejectedException; import com.android.ddmlib.IDevice; import com.android.ddmlib.IShellOutputReceiver; import com.android.ddmlib.ShellCommandUnresponsiveException; import com.android.ddmlib.TimeoutException; import com.android.utils.ILogger; import com.google.common.collect.Lists; import com.google.common.util.concurrent.SettableFuture; import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; public class FakeDevice extends DeviceConnector { private final String name; private boolean connectCalled = false; private boolean disconnectCalled = false; private boolean installCalled = false; private boolean uninstallCalled = false; private boolean execShellCalled = false; private boolean pullFileCalled = false; private final List<File> installedApks = Lists.newArrayList(); FakeDevice(String name) { this.name = name; } @Override public void connect(int timeOut, ILogger logger) throws TimeoutException { logger.info("CONNECT(%S) CALLED", name); connectCalled = true; } @Override public void disconnect(int timeOut, ILogger logger) throws TimeoutException { logger.info("DISCONNECTED(%S) CALLED", name); disconnectCalled = true; } @Override public void installPackage(@NonNull File apkFile, Collection<String> installOptions, int timeout, ILogger logger) throws DeviceException { logger.info("INSTALL(%S) CALLED", name); if (apkFile == null) { throw new NullPointerException("Null testApk"); } System.out.println(String.format("\t(%s)ApkFile: %s", name, apkFile.getAbsolutePath())); if (!apkFile.isFile()) { throw new RuntimeException("Missing file: " + apkFile.getAbsolutePath()); } if (!apkFile.getAbsolutePath().endsWith(".apk")) { throw new RuntimeException("Wrong extension: " + apkFile.getAbsolutePath()); } if (installedApks.contains(apkFile)) { throw new RuntimeException("Already added: " + apkFile.getAbsolutePath()); } installedApks.add(apkFile); installCalled = true; } public void installPackages(@NonNull List<File> apkFiles, Collection<String> installOptions, int timeout, ILogger logger) throws DeviceException { if (apkFiles == null || apkFiles.isEmpty()) { throw new NullPointerException("Null testApks"); } for (File apkFile : apkFiles) { System.out.println(String.format("\t(%s)ApkFile: %s", name, apkFile.getAbsolutePath())); if (!apkFile.isFile()) { throw new RuntimeException("Missing file: " + apkFile.getAbsolutePath()); } if (!apkFile.getAbsolutePath().endsWith(".apk")) { throw new RuntimeException("Wrong extension: " + apkFile.getAbsolutePath()); } if (installedApks.contains(apkFile)) { throw new RuntimeException("Already added: " + apkFile.getAbsolutePath()); } installedApks.add(apkFile); } installCalled = true; } @Override public void uninstallPackage(@NonNull String packageName, int timeout, ILogger logger) throws DeviceException { logger.info("UNINSTALL(%S) CALLED", name); uninstallCalled = true; } @Override public String getName() { return name; } @Override public void executeShellCommand(String command, IShellOutputReceiver receiver, long maxTimeToOutputResponse, TimeUnit maxTimeUnits) throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException { System.out.println(String.format("EXECSHELL(%S) CALLED", name)); // now fake out some tests result to make the test runner happy. addLineToReceiver("INSTRUMENTATION_STATUS: numtests=2\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: numtests=2\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: stream=\r\n", receiver); addLineToReceiver("com.android.tests.basic.MainTest:\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: id=InstrumentationTestRunner\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: test=testBuildConfig\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: class=com.android.tests.basic.MainTest\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: current=1\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS_CODE: 1\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: numtests=2\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: stream=.\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: id=InstrumentationTestRunner\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: test=testBuildConfig\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: class=com.android.tests.basic.MainTest\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: current=1\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS_CODE: 0\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: numtests=2\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: stream=\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: id=InstrumentationTestRunner\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: test=testPreconditions\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: class=com.android.tests.basic.MainTest\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: current=2\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS_CODE: 1\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: numtests=2\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: stream=.\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: id=InstrumentationTestRunner\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: test=testPreconditions\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: class=com.android.tests.basic.MainTest\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS: current=2\r\n", receiver); addLineToReceiver("INSTRUMENTATION_STATUS_CODE: 0\r\n", receiver); addLineToReceiver("INSTRUMENTATION_RESULT: stream=\r\n", receiver); addLineToReceiver("Test results for InstrumentationTestRunner=..\r\n", receiver); addLineToReceiver("Time: 0.247\r\n", receiver); addLineToReceiver("\r\n", receiver); addLineToReceiver("OK (2 tests)\r\n", receiver); receiver.flush(); execShellCalled = true; } private void addLineToReceiver(String line, IShellOutputReceiver receiver) { byte[] bytes = line.getBytes(); receiver.addOutput(bytes, 0, bytes.length); } @Override public void pullFile(String remote, String local) throws IOException { System.out.println(String.format("PULL_FILE(%S) CALLED", name)); pullFileCalled = true; } public String isValid() { if (!connectCalled) { return "connect not called on " + name; } if (!disconnectCalled) { return "disconnect not called on " + name; } if (!installCalled) { return "installPackage not called on " + name; } if (!uninstallCalled) { return "uninstallPackage not called on " + name; } if (!execShellCalled) { return "executeShellCommand not called on " + name; } if (!pullFileCalled) { return "pullFile not called on " + name; } return null; } public String getSerialNumber() { return "1234"; } public IDevice.DeviceState getState() { return IDevice.DeviceState.ONLINE; } public int getApiLevel() { return 99; } public String getApiCodeName() { return null; } @NonNull public List<String> getAbis() { return Collections.singletonList("fake"); } public int getDensity() { return 160; } public int getHeight() { return 800; } public int getWidth() { return 480; } public String getLanguage() { return "en"; } public String getRegion() { return null; } public String getProperty(String propertyName) { if ("ro.sf.lcd_density".equals(propertyName)) return "160"; return null; } public Future<String> getSystemProperty(@NonNull String name) { return SettableFuture.create(); } public DeviceConfig getDeviceConfig() { return DeviceConfig.Builder.parse(Collections.<String>emptyList()); } }