chimpchat

16:33:28.691 INFO  jd.cli.Main - Decompiling chimpchat.jar
package com.android.chimpchat;

import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpBackend;
import com.android.chimpchat.core.IChimpDevice;
import java.util.Map;
import java.util.TreeMap;

public class ChimpChat
{
  private final IChimpBackend mBackend;
  private static String sAdbLocation;
  private static boolean sNoInitAdb;
  
  private ChimpChat(IChimpBackend backend)
  {
    mBackend = backend;
  }
  
  public static ChimpChat getInstance(Map<String, String> options)
  {
    sAdbLocation = (String)options.get("adbLocation");
    sNoInitAdb = Boolean.valueOf((String)options.get("noInitAdb")).booleanValue();
    
    IChimpBackend backend = createBackendByName((String)options.get("backend"));
    if (backend == null) {
      return null;
    }
    ChimpChat chimpchat = new ChimpChat(backend);
    return chimpchat;
  }
  
  public static ChimpChat getInstance()
  {
    Map<String, String> options = new TreeMap();
    options.put("backend", "adb");
    return getInstance(options);
  }
  
  private static IChimpBackend createBackendByName(String backendName)
  {
    if ("adb".equals(backendName)) {
      return new AdbBackend(sAdbLocation, sNoInitAdb);
    }
    return null;
  }
  
  public IChimpDevice waitForConnection(long timeoutMs, String deviceId)
  {
    return mBackend.waitForConnection(timeoutMs, deviceId);
  }
  
  public IChimpDevice waitForConnection()
  {
    return mBackend.waitForConnection(2147483647L, ".*");
  }
  
  public void shutdown()
  {
    mBackend.shutdown();
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.ChimpChat
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat;

import com.android.chimpchat.core.ChimpException;
import com.android.chimpchat.core.ChimpView;
import com.android.chimpchat.core.IChimpView;
import com.android.chimpchat.core.PhysicalButton;
import com.google.common.collect.Lists;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.SocketException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ChimpManager
{
  private static Logger LOG = Logger.getLogger(ChimpManager.class.getName());
  private Socket monkeySocket;
  private BufferedWriter monkeyWriter;
  private BufferedReader monkeyReader;
  
  public ChimpManager(Socket monkeySocket)
    throws IOException
  {
    this.monkeySocket = monkeySocket;
    monkeyWriter = new BufferedWriter(new OutputStreamWriter(monkeySocket.getOutputStream()));
    
    monkeyReader = new BufferedReader(new InputStreamReader(monkeySocket.getInputStream()));
  }
  
  protected void finalize()
    throws Throwable
  {
    try
    {
      quit();
    }
    finally
    {
      close();
      super.finalize();
    }
  }
  
  public boolean touchDown(int x, int y)
    throws IOException
  {
    return sendMonkeyEvent("touch down " + x + " " + y);
  }
  
  public boolean touchUp(int x, int y)
    throws IOException
  {
    return sendMonkeyEvent("touch up " + x + " " + y);
  }
  
  public boolean touchMove(int x, int y)
    throws IOException
  {
    return sendMonkeyEvent("touch move " + x + " " + y);
  }
  
  public boolean touch(int x, int y)
    throws IOException
  {
    return sendMonkeyEvent("tap " + x + " " + y);
  }
  
  public boolean press(String name)
    throws IOException
  {
    return sendMonkeyEvent("press " + name);
  }
  
  public boolean keyDown(String name)
    throws IOException
  {
    return sendMonkeyEvent("key down " + name);
  }
  
  public boolean keyUp(String name)
    throws IOException
  {
    return sendMonkeyEvent("key up " + name);
  }
  
  public boolean press(PhysicalButton button)
    throws IOException
  {
    return press(button.getKeyName());
  }
  
  private String sendMonkeyEventAndGetResponse(String command)
    throws IOException
  {
    command = command.trim();
    LOG.info("Monkey Command: " + command + ".");
    
    monkeyWriter.write(command + "\n");
    monkeyWriter.flush();
    return monkeyReader.readLine();
  }
  
  private boolean parseResponseForSuccess(String monkeyResponse)
  {
    if (monkeyResponse == null) {
      return false;
    }
    if (monkeyResponse.startsWith("OK")) {
      return true;
    }
    return false;
  }
  
  private String parseResponseForExtra(String monkeyResponse)
  {
    int offset = monkeyResponse.indexOf(':');
    if (offset < 0) {
      return "";
    }
    return monkeyResponse.substring(offset + 1);
  }
  
  private boolean sendMonkeyEvent(String command)
    throws IOException
  {
    synchronized (this)
    {
      String monkeyResponse = sendMonkeyEventAndGetResponse(command);
      return parseResponseForSuccess(monkeyResponse);
    }
  }
  
  public void close()
  {
    try
    {
      monkeySocket.close();
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to close monkeySocket", e);
    }
    try
    {
      monkeyReader.close();
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to close monkeyReader", e);
    }
    try
    {
      monkeyWriter.close();
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to close monkeyWriter", e);
    }
  }
  
  public String getVariable(String name)
    throws IOException
  {
    synchronized (this)
    {
      String response = sendMonkeyEventAndGetResponse("getvar " + name);
      if (!parseResponseForSuccess(response)) {
        return null;
      }
      return parseResponseForExtra(response);
    }
  }
  
  public Collection<String> listVariable()
    throws IOException
  {
    synchronized (this)
    {
      String response = sendMonkeyEventAndGetResponse("listvar");
      if (!parseResponseForSuccess(response)) {
        Collections.emptyList();
      }
      String extras = parseResponseForExtra(response);
      return Lists.newArrayList(extras.split(" "));
    }
  }
  
  public void done()
    throws IOException
  {
    synchronized (this)
    {
      sendMonkeyEventAndGetResponse("done");
    }
  }
  
  public void quit()
    throws IOException
  {
    synchronized (this)
    {
      try
      {
        sendMonkeyEventAndGetResponse("quit");
      }
      catch (SocketException e) {}
    }
  }
  
  public boolean tap(int x, int y)
    throws IOException
  {
    return sendMonkeyEvent("tap " + x + " " + y);
  }
  
  public boolean type(String text)
    throws IOException
  {
    StringTokenizer tok = new StringTokenizer(text, "\n", true);
    while (tok.hasMoreTokens())
    {
      String line = tok.nextToken();
      if ("\n".equals(line))
      {
        boolean success = press(PhysicalButton.ENTER);
        if (!success) {
          return false;
        }
      }
      else
      {
        boolean success = sendMonkeyEvent("type " + line);
        if (!success) {
          return false;
        }
      }
    }
    return true;
  }
  
  public boolean type(char keyChar)
    throws IOException
  {
    return type(Character.toString(keyChar));
  }
  
  public void wake()
    throws IOException
  {
    sendMonkeyEvent("wake");
  }
  
  public Collection<String> listViewIds()
    throws IOException
  {
    synchronized (this)
    {
      String response = sendMonkeyEventAndGetResponse("listviews");
      if (!parseResponseForSuccess(response)) {
        Collections.emptyList();
      }
      String extras = parseResponseForExtra(response);
      return Lists.newArrayList(extras.split(" "));
    }
  }
  
  public String queryView(String idType, List<String> ids, String query)
    throws IOException
  {
    StringBuilder monkeyCommand = new StringBuilder("queryview " + idType + " ");
    for (String id : ids) {
      monkeyCommand.append(id).append(" ");
    }
    monkeyCommand.append(query);
    synchronized (this)
    {
      String response = sendMonkeyEventAndGetResponse(monkeyCommand.toString());
      if (!parseResponseForSuccess(response)) {
        throw new ChimpException(parseResponseForExtra(response));
      }
      return parseResponseForExtra(response);
    }
  }
  
  public IChimpView getRootView()
    throws IOException
  {
    synchronized (this)
    {
      String response = sendMonkeyEventAndGetResponse("getrootview");
      String extra = parseResponseForExtra(response);
      List<String> ids = Arrays.asList(extra.split(" "));
      if ((!parseResponseForSuccess(response)) || (ids.size() != 2)) {
        throw new ChimpException(extra);
      }
      ChimpView root = new ChimpView("accessibilityids", ids);
      root.setManager(this);
      return root;
    }
  }
  
  public String getViewsWithText(String text)
    throws IOException
  {
    synchronized (this)
    {
      if (text.split(" ").length > 1) {
        text = "\"" + text + "\"";
      }
      String response = sendMonkeyEventAndGetResponse("getviewswithtext " + text);
      if (!parseResponseForSuccess(response)) {
        throw new ChimpException(parseResponseForExtra(response));
      }
      return parseResponseForExtra(response);
    }
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.ChimpManager
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

import com.android.SdkConstants;
import com.android.chimpchat.core.IChimpBackend;
import com.android.chimpchat.core.IChimpDevice;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IDevice.DeviceState;
import com.google.common.collect.Lists;
import java.io.File;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AdbBackend
  implements IChimpBackend
{
  private static Logger LOG = Logger.getLogger(AdbBackend.class.getCanonicalName());
  private static final int CONNECTION_ITERATION_TIMEOUT_MS = 200;
  private final List<IChimpDevice> devices = Lists.newArrayList();
  private final AndroidDebugBridge bridge;
  private final boolean initAdb;
  
  public AdbBackend()
  {
    this(null, false);
  }
  
  public AdbBackend(String adbLocation, boolean noInitAdb)
  {
    initAdb = (!noInitAdb);
    if (adbLocation == null) {
      adbLocation = findAdb();
    }
    if (initAdb) {
      AndroidDebugBridge.init(false);
    }
    bridge = AndroidDebugBridge.createBridge(adbLocation, true);
  }
  
  private String findAdb()
  {
    String mrParentLocation = System.getProperty("com.android.monkeyrunner.bindir");
    if ((mrParentLocation != null) && (mrParentLocation.length() != 0))
    {
      File platformTools = new File(new File(mrParentLocation).getParent(), "platform-tools");
      if (platformTools.isDirectory()) {
        return platformTools.getAbsolutePath() + File.separator + SdkConstants.FN_ADB;
      }
      return mrParentLocation + File.separator + SdkConstants.FN_ADB;
    }
    return SdkConstants.FN_ADB;
  }
  
  private IDevice findAttachedDevice(String deviceIdRegex)
  {
    Pattern pattern = Pattern.compile(deviceIdRegex);
    for (IDevice device : bridge.getDevices())
    {
      String serialNumber = device.getSerialNumber();
      if (pattern.matcher(serialNumber).matches()) {
        return device;
      }
    }
    return null;
  }
  
  public IChimpDevice waitForConnection()
  {
    return waitForConnection(2147483647L, ".*");
  }
  
  public IChimpDevice waitForConnection(long timeoutMs, String deviceIdRegex)
  {
    do
    {
      IDevice device = findAttachedDevice(deviceIdRegex);
      if ((device != null) && (device.getState() == IDevice.DeviceState.ONLINE))
      {
        IChimpDevice chimpDevice = new AdbChimpDevice(device);
        devices.add(chimpDevice);
        return chimpDevice;
      }
      try
      {
        Thread.sleep(200L);
      }
      catch (InterruptedException e)
      {
        LOG.log(Level.SEVERE, "Error sleeping", e);
      }
      timeoutMs -= 200L;
    } while (timeoutMs > 0L);
    return null;
  }
  
  public void shutdown()
  {
    for (IChimpDevice device : devices) {
      device.dispose();
    }
    if (initAdb) {
      AndroidDebugBridge.terminate();
    }
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.AdbBackend
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.TimeoutException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

class AdbChimpDevice$1
  implements Runnable
{
  AdbChimpDevice$1(AdbChimpDevice paramAdbChimpDevice, String paramString, LoggingOutputReceiver paramLoggingOutputReceiver) {}
  
  public void run()
  {
    try
    {
      AdbChimpDevice.access$000(this$0).executeShellCommand(val$command, val$logger);
    }
    catch (TimeoutException e)
    {
      AdbChimpDevice.access$100().log(Level.SEVERE, "Error starting command: " + val$command, e);
      throw new RuntimeException(e);
    }
    catch (AdbCommandRejectedException e)
    {
      AdbChimpDevice.access$100().log(Level.SEVERE, "Error starting command: " + val$command, e);
      throw new RuntimeException(e);
    }
    catch (ShellCommandUnresponsiveException e)
    {
      AdbChimpDevice.access$100().log(Level.INFO, "Error starting command: " + val$command, e);
      throw new RuntimeException(e);
    }
    catch (IOException e)
    {
      AdbChimpDevice.access$100().log(Level.SEVERE, "Error starting command: " + val$command, e);
      throw new RuntimeException(e);
    }
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.AdbChimpDevice.1
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

import com.android.chimpchat.ChimpManager;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

class AdbChimpDevice$2
  implements LinearInterpolator.Callback
{
  AdbChimpDevice$2(AdbChimpDevice paramAdbChimpDevice, long paramLong) {}
  
  public void step(LinearInterpolator.Point point)
  {
    try
    {
      AdbChimpDevice.access$200(this$0).touchMove(point.getX(), point.getY());
    }
    catch (IOException e)
    {
      AdbChimpDevice.access$100().log(Level.SEVERE, "Error sending drag start event", e);
    }
    try
    {
      Thread.sleep(val$iterationTime);
    }
    catch (InterruptedException e)
    {
      AdbChimpDevice.access$100().log(Level.SEVERE, "Error sleeping", e);
    }
  }
  
  public void start(LinearInterpolator.Point point)
  {
    try
    {
      AdbChimpDevice.access$200(this$0).touchDown(point.getX(), point.getY());
      AdbChimpDevice.access$200(this$0).touchMove(point.getX(), point.getY());
    }
    catch (IOException e)
    {
      AdbChimpDevice.access$100().log(Level.SEVERE, "Error sending drag start event", e);
    }
    try
    {
      Thread.sleep(val$iterationTime);
    }
    catch (InterruptedException e)
    {
      AdbChimpDevice.access$100().log(Level.SEVERE, "Error sleeping", e);
    }
  }
  
  public void end(LinearInterpolator.Point point)
  {
    try
    {
      AdbChimpDevice.access$200(this$0).touchMove(point.getX(), point.getY());
      AdbChimpDevice.access$200(this$0).touchUp(point.getX(), point.getY());
    }
    catch (IOException e)
    {
      AdbChimpDevice.access$100().log(Level.SEVERE, "Error sending drag end event", e);
    }
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.AdbChimpDevice.2
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

class AdbChimpDevice$3 {}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.AdbChimpDevice.3
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

import com.android.annotations.Nullable;
import com.android.chimpchat.ChimpManager;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;
import com.android.chimpchat.core.IChimpView;
import com.android.chimpchat.core.IMultiSelector;
import com.android.chimpchat.core.ISelector;
import com.android.chimpchat.core.PhysicalButton;
import com.android.chimpchat.core.TouchPressType;
import com.android.chimpchat.hierarchyviewer.HierarchyViewer;
import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.InstallException;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.TimeoutException;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AdbChimpDevice
  implements IChimpDevice
{
  private static final Logger LOG = Logger.getLogger(AdbChimpDevice.class.getName());
  private static final String[] ZERO_LENGTH_STRING_ARRAY = new String[0];
  private static final long MANAGER_CREATE_TIMEOUT_MS = 30000L;
  private static final long MANAGER_CREATE_WAIT_TIME_MS = 1000L;
  private final ExecutorService executor = Executors.newSingleThreadExecutor();
  private final IDevice device;
  private ChimpManager manager;
  
  public AdbChimpDevice(IDevice device)
  {
    this.device = device;
    manager = createManager("127.0.0.1", 12345);
    
    Preconditions.checkNotNull(manager);
  }
  
  public ChimpManager getManager()
  {
    return manager;
  }
  
  public void dispose()
  {
    try
    {
      manager.quit();
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Error getting the manager to quit", e);
    }
    manager.close();
    executor.shutdown();
    manager = null;
  }
  
  public HierarchyViewer getHierarchyViewer()
  {
    return new HierarchyViewer(device);
  }
  
  private void executeAsyncCommand(final String command, final LoggingOutputReceiver logger)
  {
    executor.submit(new Runnable()
    {
      public void run()
      {
        try
        {
          device.executeShellCommand(command, logger);
        }
        catch (TimeoutException e)
        {
          AdbChimpDevice.LOG.log(Level.SEVERE, "Error starting command: " + command, e);
          throw new RuntimeException(e);
        }
        catch (AdbCommandRejectedException e)
        {
          AdbChimpDevice.LOG.log(Level.SEVERE, "Error starting command: " + command, e);
          throw new RuntimeException(e);
        }
        catch (ShellCommandUnresponsiveException e)
        {
          AdbChimpDevice.LOG.log(Level.INFO, "Error starting command: " + command, e);
          throw new RuntimeException(e);
        }
        catch (IOException e)
        {
          AdbChimpDevice.LOG.log(Level.SEVERE, "Error starting command: " + command, e);
          throw new RuntimeException(e);
        }
      }
    });
  }
  
  private ChimpManager createManager(String address, int port)
  {
    try
    {
      device.createForward(port, port);
    }
    catch (TimeoutException e)
    {
      LOG.log(Level.SEVERE, "Timeout creating adb port forwarding", e);
      return null;
    }
    catch (AdbCommandRejectedException e)
    {
      LOG.log(Level.SEVERE, "Adb rejected adb port forwarding command: " + e.getMessage(), e);
      return null;
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to create adb port forwarding: " + e.getMessage(), e);
      return null;
    }
    String command = "monkey --port " + port;
    executeAsyncCommand(command, new LoggingOutputReceiver(LOG, Level.FINE));
    try
    {
      Thread.sleep(1000L);
    }
    catch (InterruptedException e)
    {
      LOG.log(Level.SEVERE, "Unable to sleep", e);
    }
    InetAddress addr;
    try
    {
      addr = InetAddress.getByName(address);
    }
    catch (UnknownHostException e)
    {
      LOG.log(Level.SEVERE, "Unable to convert address into InetAddress: " + address, e);
      return null;
    }
    boolean success = false;
    ChimpManager mm = null;
    long start = System.currentTimeMillis();
    while (!success)
    {
      long now = System.currentTimeMillis();
      long diff = now - start;
      if (diff > 30000L)
      {
        LOG.severe("Timeout while trying to create chimp mananger");
        return null;
      }
      try
      {
        Thread.sleep(1000L);
      }
      catch (InterruptedException e)
      {
        LOG.log(Level.SEVERE, "Unable to sleep", e);
      }
      Socket monkeySocket;
      try
      {
        monkeySocket = new Socket(addr, port);
      }
      catch (IOException e)
      {
        LOG.log(Level.FINE, "Unable to connect socket", e);
        success = false;
      }
      continue;
      try
      {
        mm = new ChimpManager(monkeySocket);
      }
      catch (IOException e)
      {
        LOG.log(Level.SEVERE, "Unable to open writer and reader to socket");
      }
      continue;
      try
      {
        mm.wake();
      }
      catch (IOException e)
      {
        LOG.log(Level.FINE, "Unable to wake up device", e);
        success = false;
      }
      continue;
      
      success = true;
    }
    return mm;
  }
  
  public IChimpImage takeSnapshot()
  {
    try
    {
      return new AdbChimpImage(device.getScreenshot());
    }
    catch (TimeoutException e)
    {
      LOG.log(Level.SEVERE, "Unable to take snapshot", e);
      return null;
    }
    catch (AdbCommandRejectedException e)
    {
      LOG.log(Level.SEVERE, "Unable to take snapshot", e);
      return null;
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to take snapshot", e);
    }
    return null;
  }
  
  public String getSystemProperty(String key)
  {
    return device.getProperty(key);
  }
  
  public String getProperty(String key)
  {
    try
    {
      return manager.getVariable(key);
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to get variable: " + key, e);
    }
    return null;
  }
  
  public Collection<String> getPropertyList()
  {
    try
    {
      return manager.listVariable();
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to get variable list", e);
    }
    return null;
  }
  
  public void wake()
  {
    try
    {
      manager.wake();
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to wake device (too sleepy?)", e);
    }
  }
  
  private String shell(String... args)
  {
    StringBuilder cmd = new StringBuilder();
    for (String arg : args) {
      cmd.append(arg).append(" ");
    }
    return shell(cmd.toString());
  }
  
  public String shell(String cmd)
  {
    return shell(cmd, 5000);
  }
  
  public String shell(String cmd, int timeout)
  {
    CommandOutputCapture capture = new CommandOutputCapture();
    try
    {
      device.executeShellCommand(cmd, capture, timeout);
    }
    catch (TimeoutException e)
    {
      LOG.log(Level.SEVERE, "Error executing command: " + cmd, e);
      return null;
    }
    catch (ShellCommandUnresponsiveException e)
    {
      LOG.log(Level.SEVERE, "Error executing command: " + cmd, e);
      return null;
    }
    catch (AdbCommandRejectedException e)
    {
      LOG.log(Level.SEVERE, "Error executing command: " + cmd, e);
      return null;
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Error executing command: " + cmd, e);
      return null;
    }
    return capture.toString();
  }
  
  public boolean installPackage(String path)
  {
    try
    {
      String result = device.installPackage(path, true, new String[0]);
      if (result != null)
      {
        LOG.log(Level.SEVERE, "Got error installing package: " + result);
        return false;
      }
      return true;
    }
    catch (InstallException e)
    {
      LOG.log(Level.SEVERE, "Error installing package: " + path, e);
    }
    return false;
  }
  
  public boolean removePackage(String packageName)
  {
    try
    {
      String result = device.uninstallPackage(packageName);
      if (result != null)
      {
        LOG.log(Level.SEVERE, "Got error uninstalling package " + packageName + ": " + result);
        
        return false;
      }
      return true;
    }
    catch (InstallException e)
    {
      LOG.log(Level.SEVERE, "Error installing package: " + packageName, e);
    }
    return false;
  }
  
  public void press(String keyName, TouchPressType type)
  {
    try
    {
      switch (type)
      {
      case DOWN_AND_UP: 
        manager.press(keyName);
        break;
      case DOWN: 
        manager.keyDown(keyName);
        break;
      case UP: 
        manager.keyUp(keyName);
      }
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Error sending press event: " + keyName + " " + type, e);
    }
  }
  
  public void press(PhysicalButton key, TouchPressType type)
  {
    press(key.getKeyName(), type);
  }
  
  public void type(String string)
  {
    try
    {
      manager.type(string);
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Error Typing: " + string, e);
    }
  }
  
  public void touch(int x, int y, TouchPressType type)
  {
    try
    {
      switch (type)
      {
      case DOWN: 
        manager.touchDown(x, y);
        break;
      case UP: 
        manager.touchUp(x, y);
        break;
      case DOWN_AND_UP: 
        manager.tap(x, y);
        break;
      case MOVE: 
        manager.touchMove(x, y);
      }
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Error sending touch event: " + x + " " + y + " " + type, e);
    }
  }
  
  public void reboot(String into)
  {
    try
    {
      device.reboot(into);
    }
    catch (TimeoutException e)
    {
      LOG.log(Level.SEVERE, "Unable to reboot device", e);
    }
    catch (AdbCommandRejectedException e)
    {
      LOG.log(Level.SEVERE, "Unable to reboot device", e);
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Unable to reboot device", e);
    }
  }
  
  public void startActivity(String uri, String action, String data, String mimetype, Collection<String> categories, Map<String, Object> extras, String component, int flags)
  {
    List<String> intentArgs = buildIntentArgString(uri, action, data, mimetype, categories, extras, component, flags);
    
    shell((String[])Lists.asList("am", "start", intentArgs.toArray(ZERO_LENGTH_STRING_ARRAY)).toArray(ZERO_LENGTH_STRING_ARRAY));
  }
  
  public void broadcastIntent(String uri, String action, String data, String mimetype, Collection<String> categories, Map<String, Object> extras, String component, int flags)
  {
    List<String> intentArgs = buildIntentArgString(uri, action, data, mimetype, categories, extras, component, flags);
    
    shell((String[])Lists.asList("am", "broadcast", intentArgs.toArray(ZERO_LENGTH_STRING_ARRAY)).toArray(ZERO_LENGTH_STRING_ARRAY));
  }
  
  private static boolean isNullOrEmpty(@Nullable String string)
  {
    return (string == null) || (string.length() == 0);
  }
  
  private List<String> buildIntentArgString(String uri, String action, String data, String mimetype, Collection<String> categories, Map<String, Object> extras, String component, int flags)
  {
    List<String> parts = Lists.newArrayList();
    if (!isNullOrEmpty(action))
    {
      parts.add("-a");
      parts.add(action);
    }
    if (!isNullOrEmpty(data))
    {
      parts.add("-d");
      parts.add(data);
    }
    if (!isNullOrEmpty(mimetype))
    {
      parts.add("-t");
      parts.add(mimetype);
    }
    for (String category : categories)
    {
      parts.add("-c");
      parts.add(category);
    }
    for (Map.Entry<String, Object> entry : extras.entrySet())
    {
      Object value = entry.getValue();
      String arg;
      String valueString;
      String arg;
      if ((value instanceof Integer))
      {
        String valueString = Integer.toString(((Integer)value).intValue());
        arg = "--ei";
      }
      else
      {
        String arg;
        if ((value instanceof Boolean))
        {
          String valueString = Boolean.toString(((Boolean)value).booleanValue());
          arg = "--ez";
        }
        else
        {
          valueString = value.toString();
          arg = "--es";
        }
      }
      parts.add(arg);
      parts.add(entry.getKey());
      parts.add(valueString);
    }
    if (!isNullOrEmpty(component))
    {
      parts.add("-n");
      parts.add(component);
    }
    if (flags != 0)
    {
      parts.add("-f");
      parts.add(Integer.toString(flags));
    }
    if (!isNullOrEmpty(uri)) {
      parts.add(uri);
    }
    return parts;
  }
  
  public Map<String, Object> instrument(String packageName, Map<String, Object> args)
  {
    List<String> shellCmd = Lists.newArrayList(new String[] { "am", "instrument", "-w", "-r" });
    for (Map.Entry<String, Object> entry : args.entrySet())
    {
      String key = (String)entry.getKey();
      Object value = entry.getValue();
      if ((key != null) && (value != null))
      {
        shellCmd.add("-e");
        shellCmd.add(key);
        shellCmd.add(value.toString());
      }
    }
    shellCmd.add(packageName);
    String result = shell((String[])shellCmd.toArray(ZERO_LENGTH_STRING_ARRAY));
    return convertInstrumentResult(result);
  }
  
  @VisibleForTesting
  static Map<String, Object> convertInstrumentResult(String result)
  {
    Map<String, Object> map = Maps.newHashMap();
    Pattern pattern = Pattern.compile("^INSTRUMENTATION_(\\w+): ", 8);
    Matcher matcher = pattern.matcher(result);
    
    int previousEnd = 0;
    String previousWhich = null;
    while (matcher.find())
    {
      if ("RESULT".equals(previousWhich))
      {
        String resultLine = result.substring(previousEnd, matcher.start()).trim();
        
        int splitIndex = resultLine.indexOf("=");
        String key = resultLine.substring(0, splitIndex);
        String value = resultLine.substring(splitIndex + 1);
        
        map.put(key, value);
      }
      previousEnd = matcher.end();
      previousWhich = matcher.group(1);
    }
    if ("RESULT".equals(previousWhich))
    {
      String resultLine = result.substring(previousEnd, matcher.start()).trim();
      
      int splitIndex = resultLine.indexOf("=");
      String key = resultLine.substring(0, splitIndex);
      String value = resultLine.substring(splitIndex + 1);
      
      map.put(key, value);
    }
    return map;
  }
  
  public void drag(int startx, int starty, int endx, int endy, int steps, long ms)
  {
    final long iterationTime = ms / steps;
    
    LinearInterpolator lerp = new LinearInterpolator(steps);
    LinearInterpolator.Point start = new LinearInterpolator.Point(startx, starty);
    LinearInterpolator.Point end = new LinearInterpolator.Point(endx, endy);
    lerp.interpolate(start, end, new LinearInterpolator.Callback()
    {
      public void step(LinearInterpolator.Point point)
      {
        try
        {
          manager.touchMove(point.getX(), point.getY());
        }
        catch (IOException e)
        {
          AdbChimpDevice.LOG.log(Level.SEVERE, "Error sending drag start event", e);
        }
        try
        {
          Thread.sleep(iterationTime);
        }
        catch (InterruptedException e)
        {
          AdbChimpDevice.LOG.log(Level.SEVERE, "Error sleeping", e);
        }
      }
      
      public void start(LinearInterpolator.Point point)
      {
        try
        {
          manager.touchDown(point.getX(), point.getY());
          manager.touchMove(point.getX(), point.getY());
        }
        catch (IOException e)
        {
          AdbChimpDevice.LOG.log(Level.SEVERE, "Error sending drag start event", e);
        }
        try
        {
          Thread.sleep(iterationTime);
        }
        catch (InterruptedException e)
        {
          AdbChimpDevice.LOG.log(Level.SEVERE, "Error sleeping", e);
        }
      }
      
      public void end(LinearInterpolator.Point point)
      {
        try
        {
          manager.touchMove(point.getX(), point.getY());
          manager.touchUp(point.getX(), point.getY());
        }
        catch (IOException e)
        {
          AdbChimpDevice.LOG.log(Level.SEVERE, "Error sending drag end event", e);
        }
      }
    });
  }
  
  public Collection<String> getViewIdList()
  {
    try
    {
      return manager.listViewIds();
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Error retrieving view IDs", e);
    }
    return new ArrayList();
  }
  
  public IChimpView getView(ISelector selector)
  {
    return selector.getView(manager);
  }
  
  public Collection<IChimpView> getViews(IMultiSelector selector)
  {
    return selector.getViews(manager);
  }
  
  public IChimpView getRootView()
  {
    try
    {
      return manager.getRootView();
    }
    catch (IOException e)
    {
      LOG.log(Level.SEVERE, "Error retrieving root view");
    }
    return null;
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.AdbChimpDevice
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

import com.android.chimpchat.adb.image.ImageUtils;
import com.android.chimpchat.core.ChimpImageBase;
import com.android.ddmlib.RawImage;
import java.awt.image.BufferedImage;

public class AdbChimpImage
  extends ChimpImageBase
{
  private final RawImage image;
  
  AdbChimpImage(RawImage image)
  {
    this.image = image;
  }
  
  public BufferedImage createBufferedImage()
  {
    return ImageUtils.convertImage(image);
  }
  
  public RawImage getRawImage()
  {
    return image;
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.AdbChimpImage
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

import com.android.ddmlib.IShellOutputReceiver;

public class CommandOutputCapture
  implements IShellOutputReceiver
{
  private final StringBuilder builder = new StringBuilder();
  
  public void flush() {}
  
  public boolean isCancelled()
  {
    return false;
  }
  
  public void addOutput(byte[] data, int offset, int length)
  {
    String message = new String(data, offset, length);
    builder.append(message);
  }
  
  public String toString()
  {
    return builder.toString();
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.CommandOutputCapture
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

public abstract interface LinearInterpolator$Callback
{
  public abstract void start(LinearInterpolator.Point paramPoint);
  
  public abstract void end(LinearInterpolator.Point paramPoint);
  
  public abstract void step(LinearInterpolator.Point paramPoint);
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.LinearInterpolator.Callback
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

public class LinearInterpolator$Point
{
  private final int x;
  private final int y;
  
  public LinearInterpolator$Point(int x, int y)
  {
    this.x = x;
    this.y = y;
  }
  
  public String toString()
  {
    return "(" + x + "," + y + ")";
  }
  
  public boolean equals(Object obj)
  {
    if ((obj instanceof Point))
    {
      Point that = (Point)obj;
      return (x == x) && (y == y);
    }
    return false;
  }
  
  public int hashCode()
  {
    return 1125274389 + x + y;
  }
  
  public int getX()
  {
    return x;
  }
  
  public int getY()
  {
    return y;
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.LinearInterpolator.Point
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

public class LinearInterpolator
{
  private final int steps;
  
  public static abstract interface Callback
  {
    public abstract void start(LinearInterpolator.Point paramPoint);
    
    public abstract void end(LinearInterpolator.Point paramPoint);
    
    public abstract void step(LinearInterpolator.Point paramPoint);
  }
  
  public static class Point
  {
    private final int x;
    private final int y;
    
    public Point(int x, int y)
    {
      this.x = x;
      this.y = y;
    }
    
    public String toString()
    {
      return "(" + x + "," + y + ")";
    }
    
    public boolean equals(Object obj)
    {
      if ((obj instanceof Point))
      {
        Point that = (Point)obj;
        return (x == x) && (y == y);
      }
      return false;
    }
    
    public int hashCode()
    {
      return 1125274389 + x + y;
    }
    
    public int getX()
    {
      return x;
    }
    
    public int getY()
    {
      return y;
    }
  }
  
  public LinearInterpolator(int steps)
  {
    this.steps = steps;
  }
  
  private static float lerp(float start, float stop, float amount)
  {
    return start + (stop - start) * amount;
  }
  
  public void interpolate(Point start, Point end, Callback callback)
  {
    int xDistance = Math.abs(end.getX() - start.getX());
    int yDistance = Math.abs(end.getY() - start.getY());
    float amount = (float)(1.0D / steps);
    
    callback.start(start);
    for (int i = 1; i < steps; i++)
    {
      float newX = lerp(start.getX(), end.getX(), amount * i);
      float newY = lerp(start.getY(), end.getY(), amount * i);
      
      callback.step(new Point(Math.round(newX), Math.round(newY)));
    }
    callback.end(end);
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.LinearInterpolator
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb;

import com.android.ddmlib.IShellOutputReceiver;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LoggingOutputReceiver
  implements IShellOutputReceiver
{
  private final Logger log;
  private final Level level;
  
  public LoggingOutputReceiver(Logger log, Level level)
  {
    this.log = log;
    this.level = level;
  }
  
  public void addOutput(byte[] data, int offset, int length)
  {
    String message = new String(data, offset, length);
    for (String line : message.split("\n")) {
      log.log(level, line);
    }
  }
  
  public void flush() {}
  
  public boolean isCancelled()
  {
    return false;
  }
}

/* Location:
 * Qualified Name:     com.android.chimpchat.adb.LoggingOutputReceiver
 * Java Class Version: 6 (50.0)
 * JD-Core Version:    0.7.1
 */
package com.android.chimpchat.adb.image;

import com.android.ddmlib.RawImage;
import java.io.Serializable;

public class CaptureRawAndConvertedImage$ChimpRawImage
  implements Serializable, CaptureRawAndConvertedImage.IRawImager
{
  public int version;
  public int bpp;
  public int size;
  public int width;
  public int height;
  public int red_offset;
  public int red_length;
  public int blue_offset;
  public int blue_length;
  public int green_offset;
  public int green_length;
  public int alpha_offset;
  public int alpha_length;
  public byte[] data;
  
  public CaptureRawAndConvertedImage$ChimpRawImage(RawImage rawImage)
  {
    version = version;
    bpp = bpp;
    size = size;
    width = width;
    height = height;
    red_offset = red_offset;
    red_length = red_length;
    blue_offset = blue_offse
1 2

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2017. Infinite Loop Ltd