AdbUtils.java revision f4bf552b5a5046e7648f405115ee48917b15b9aa
1package com.android.dumprendertree.forwarder;
2
3import android.util.Log;
4
5import java.io.DataInputStream;
6import java.io.IOException;
7import java.io.InputStream;
8import java.io.OutputStream;
9import java.net.Socket;
10
11public class AdbUtils {
12
13    private static final String ADB_OK = "OKAY";
14    private static final int ADB_PORT = 5037;
15    private static final String ADB_HOST = "127.0.0.1";
16    private static final int ADB_RESPONSE_SIZE = 4;
17
18    private static final String LOGTAG = "AdbUtils";
19
20    /**
21     *
22     * Convert integer format IP into xxx.xxx.xxx.xxx format
23     *
24     * @param host IP address in integer format
25     * @return human readable format
26     */
27    public static String convert(int host) {
28        return ((host >> 24) & 0xFF) + "."
29        + ((host >> 16) & 0xFF) + "."
30        + ((host >> 8) & 0xFF) + "."
31        + (host & 0xFF);
32    }
33
34    /**
35     *
36     * Resolve DNS name into IP address
37     *
38     * @param host DNS name
39     * @return IP address in integer format
40     * @throws IOException
41     */
42    public static int resolve(String host)  throws IOException {
43        Socket localSocket = new Socket(ADB_HOST, ADB_PORT);
44        DataInputStream dis = new DataInputStream(localSocket.getInputStream());
45        OutputStream os = localSocket.getOutputStream();
46        int count_read = 0;
47        byte[] buf = new byte[128];
48
49        if (localSocket == null || dis == null || os == null)
50            return -1;
51        String cmd = "dns:" + host;
52
53        if(!sendAdbCmd(dis, os, cmd))
54            return -1;
55
56        count_read = dis.readInt();
57        localSocket.close();
58        return count_read;
59    }
60
61    /**
62     *
63     * Send an ADB command using existing socket connection
64     *
65     * the streams provided must be from a socket connected to adbd already
66     *
67     * @param is input stream of the socket connection
68     * @param os output stream of the socket
69     * @param cmd the adb command to send
70     * @return if adb gave a success response
71     * @throws IOException
72     */
73    public static boolean sendAdbCmd(InputStream is, OutputStream os,
74            String cmd) throws IOException {
75        byte[] buf = new byte[ADB_RESPONSE_SIZE];
76
77        cmd = String.format("%04X", cmd.length()) + cmd;
78        os.write(cmd.getBytes());
79        int read = is.read(buf);
80        if(read != ADB_RESPONSE_SIZE || !ADB_OK.equals(new String(buf))) {
81            Log.w(LOGTAG, "adb cmd faild.");
82            return false;
83        }
84        return true;
85    }
86
87    /**
88     *
89     * Get a tcp socket connection to specified IP address and port proxied by adb
90     *
91     * The proxying is transparent, e.g. if a socket is returned, then it can be written to and
92     * read from as if it is directly connected to the target
93     *
94     * @param remoteAddress IP address of the host to connect to
95     * @param remotePort port of the host to connect to
96     * @return a valid Socket instance if successful, null otherwise
97     */
98    public static Socket getForwardedSocket(int remoteAddress, int remotePort) {
99        try {
100            Socket socket = new Socket(ADB_HOST, ADB_PORT);
101            String cmd = "tcp:" + remotePort + ":" + convert(remoteAddress);
102            if(!sendAdbCmd(socket.getInputStream(), socket.getOutputStream(), cmd)) {
103                socket.close();
104                return null;
105            }
106            return socket;
107        } catch (IOException ioe) {
108            Log.w(LOGTAG, "error creating adb socket", ioe);
109            return null;
110        }
111    }
112}
113