summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/android/wds
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-13 16:40:46 +0100
committerBen Murdoch <benm@google.com>2011-05-16 11:35:03 +0100
commita2c606d1d8312a5d063e4a11e5911d9c8e4a3d19 (patch)
tree614d69ba96a23bc057e539a3c8a7d4961a68254b /Source/WebKit/android/wds
parent65f03d4f644ce73618e5f4f50dd694b26f55ae12 (diff)
downloadexternal_webkit-a2c606d1d8312a5d063e4a11e5911d9c8e4a3d19.zip
external_webkit-a2c606d1d8312a5d063e4a11e5911d9c8e4a3d19.tar.gz
external_webkit-a2c606d1d8312a5d063e4a11e5911d9c8e4a3d19.tar.bz2
Merge WebKit at r75993: Move WebKit/android files to Source
Change-Id: Ifa871f8320bdb3a09fe189fffecc23f702c394b9
Diffstat (limited to 'Source/WebKit/android/wds')
-rw-r--r--Source/WebKit/android/wds/Command.cpp154
-rw-r--r--Source/WebKit/android/wds/Command.h108
-rw-r--r--Source/WebKit/android/wds/Connection.cpp93
-rw-r--r--Source/WebKit/android/wds/Connection.h86
-rw-r--r--Source/WebKit/android/wds/DebugServer.cpp116
-rw-r--r--Source/WebKit/android/wds/DebugServer.h77
-rw-r--r--Source/WebKit/android/wds/client/AdbConnection.cpp237
-rw-r--r--Source/WebKit/android/wds/client/AdbConnection.h47
-rw-r--r--Source/WebKit/android/wds/client/Android.mk39
-rw-r--r--Source/WebKit/android/wds/client/ClientUtils.cpp35
-rw-r--r--Source/WebKit/android/wds/client/ClientUtils.h46
-rw-r--r--Source/WebKit/android/wds/client/Device.cpp31
-rw-r--r--Source/WebKit/android/wds/client/Device.h62
-rw-r--r--Source/WebKit/android/wds/client/DeviceList.h35
-rw-r--r--Source/WebKit/android/wds/client/main.cpp173
15 files changed, 1339 insertions, 0 deletions
diff --git a/Source/WebKit/android/wds/Command.cpp b/Source/WebKit/android/wds/Command.cpp
new file mode 100644
index 0000000..bd8536f
--- /dev/null
+++ b/Source/WebKit/android/wds/Command.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "wds"
+#include "config.h"
+
+#include "AndroidLog.h"
+#include "Command.h"
+#include "Connection.h"
+#include "DebugServer.h"
+#include "Frame.h"
+#include "RenderTreeAsText.h"
+#include "RenderView.h"
+#include "WebViewCore.h"
+#include <utils/Log.h>
+#include <wtf/text/CString.h>
+
+#if ENABLE(WDS)
+
+using namespace WebCore;
+
+namespace android {
+
+namespace WDS {
+
+//------------------------------------------------------------------------------
+// Actual commands -- XXX should be moved somewhere else
+//------------------------------------------------------------------------------
+static bool callDumpRenderTree(const Frame* frame, const Connection* conn) {
+ CString str = externalRepresentation(frame->contentRenderer()).latin1();
+ conn->write(str.data(), str.length());
+ return true;
+}
+
+static bool callDumpDomTree(const Frame* frame, const Connection* conn) {
+ WebViewCore::getWebViewCore(frame->view())->dumpDomTree(true);
+
+ FILE* f = fopen(DOM_TREE_LOG_FILE, "r");
+ if (!f) {
+ conn->write("Dom tree written to logcat\n");
+ } else {
+ char buf[512];
+ while (true) {
+ int nread = fread(buf, 1, sizeof(buf), f);
+ if (nread <= 0)
+ break;
+ conn->write(buf, nread);
+ }
+ fclose(f);
+ }
+ return true;
+}
+
+class WebCoreHandler : public Handler {
+public:
+ virtual void post(TargetThreadFunction func, void* v) const {
+ callOnMainThread(func, v);
+ }
+};
+static WebCoreHandler s_webcoreHandler;
+
+//------------------------------------------------------------------------------
+// End command section
+//------------------------------------------------------------------------------
+
+class InternalCommand : public Command {
+public:
+ InternalCommand(const Command* comm, const Frame* frame,
+ const Connection* connection)
+ : Command(*comm)
+ , m_frame(frame)
+ , m_connection(connection) {}
+ virtual ~InternalCommand() { delete m_connection; }
+
+ void doCommand() const {
+ LOGD("Executing command '%s' (%s)", m_name, m_description);
+ if (!m_dispatch(m_frame, m_connection))
+ // XXX: Have useful failure messages
+ m_connection->write("EPIC FAIL!\n", 11);
+ }
+
+private:
+ const Frame* m_frame;
+ const Connection* m_connection;
+};
+
+static void commandDispatcher(void* v) {
+ InternalCommand* c = static_cast<InternalCommand*>(v);
+ c->doCommand();
+ delete c;
+}
+
+void Command::dispatch() {
+ m_handler.post(commandDispatcher, this);
+}
+
+Vector<const Command*>* Command::s_commands;
+
+void Command::Init() {
+ // Do not initialize twice.
+ if (s_commands)
+ return;
+ // XXX: Move this somewhere else.
+ s_commands = new Vector<const Command*>();
+ s_commands->append(new Command("DDOM", "Dump Dom Tree",
+ callDumpDomTree, s_webcoreHandler));
+ s_commands->append(new Command("DDRT", "Dump Render Tree",
+ callDumpRenderTree, s_webcoreHandler));
+}
+
+Command* Command::Find(const Connection* conn) {
+ char buf[COMMAND_LENGTH];
+ if (conn->read(buf, sizeof(buf)) != COMMAND_LENGTH)
+ return NULL;
+
+ // Linear search of commands. TODO: binary search when more commands are
+ // added.
+ Vector<const Command*>::const_iterator i = s_commands->begin();
+ Vector<const Command*>::const_iterator end = s_commands->end();
+ while (i != end) {
+ if (strncmp(buf, (*i)->name(), sizeof(buf)) == 0)
+ return new InternalCommand(*i, server()->getFrame(0), conn);
+ i++;
+ }
+ return NULL;
+}
+
+} // end namespace WDS
+
+} // end namespace android
+
+#endif
diff --git a/Source/WebKit/android/wds/Command.h b/Source/WebKit/android/wds/Command.h
new file mode 100644
index 0000000..90861d4
--- /dev/null
+++ b/Source/WebKit/android/wds/Command.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WDS_COMMAND_H
+#define WDS_COMMAND_H
+
+#include "wtf/MainThread.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+class Frame;
+}
+
+using namespace WTF;
+using namespace WebCore;
+
+namespace android {
+
+// WebCore Debug Server
+namespace WDS {
+
+class Connection;
+
+// Command identifier length
+#define COMMAND_LENGTH 4
+
+// The dispatcher function called with a Frame for context and the established
+// connection to the client. The connection can be used to read and write to the
+// client application. Return true on successful completion of the command,
+// return false to indicate failure.
+typedef bool (*DispatchFunction)(const Frame*, const Connection*);
+
+// Note: Although the type is named MainThreadFunction, it may not always be
+// the main thread. The type is generic enough to reuse here but named
+// something more appropriate.
+typedef MainThreadFunction TargetThreadFunction;
+
+// Helper class to dipatch functions on a particular thread.
+class Handler {
+public:
+ virtual ~Handler() {}
+ virtual void post(TargetThreadFunction, void*) const = 0;
+};
+
+// Class for containing information about particular commands.
+class Command {
+public:
+ Command(const char* name, const char* desc, const DispatchFunction func,
+ const Handler& handler)
+ : m_name(name)
+ , m_description(desc)
+ , m_dispatch(func)
+ , m_handler(handler) {}
+ Command(const Command& comm)
+ : m_name(comm.m_name)
+ , m_description(comm.m_description)
+ , m_dispatch(comm.m_dispatch)
+ , m_handler(comm.m_handler) {}
+ virtual ~Command() {}
+
+ // Initialize the debug server commands
+ static void Init();
+
+ // Find the command specified by the client request.
+ static Command* Find(const Connection* conn);
+
+ // Dispatch this command
+ void dispatch();
+
+ const char* name() const { return m_name; }
+
+protected:
+ const char* m_name;
+ const char* m_description;
+ const DispatchFunction m_dispatch;
+
+private:
+ const Handler& m_handler;
+ static Vector<const Command*>* s_commands;
+};
+
+} // end namespace WDS
+
+} // end namespace android
+
+#endif
diff --git a/Source/WebKit/android/wds/Connection.cpp b/Source/WebKit/android/wds/Connection.cpp
new file mode 100644
index 0000000..d7e55ac
--- /dev/null
+++ b/Source/WebKit/android/wds/Connection.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "wds"
+#include "config.h"
+
+#include "DebugServer.h" // used for ENABLE_WDS
+#include "Connection.h"
+#include <arpa/inet.h>
+#include <string.h>
+#include <utils/Log.h>
+
+#if ENABLE(WDS)
+
+#define MAX_CONNECTION_QUEUE 5
+#define log_errno(x) LOGE("%s: %d", x, strerror(errno))
+
+namespace android {
+
+namespace WDS {
+
+bool Socket::open() {
+ m_fd = socket(PF_INET, SOCK_STREAM, 0);
+ if (m_fd < 0) {
+ log_errno("Failed to create file descriptor");
+ return false;
+ }
+ return true;
+}
+
+bool ConnectionServer::connect(short port) {
+ if (!m_socket.open())
+ return false;
+ int fd = m_socket.fd();
+
+ // Build our sockaddr_in structure use to listen to incoming connections
+ sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(port);
+
+ // Try to bind to the given port
+ if (bind(fd, (sockaddr*) &addr, sizeof(addr)) < 0) {
+ log_errno("Failed to bind to local host");
+ return false;
+ }
+
+ // Try to listen
+ if (listen(fd, MAX_CONNECTION_QUEUE) < 0) {
+ log_errno("Failed to listen");
+ return false;
+ }
+
+ return true;
+}
+
+Connection* ConnectionServer::accept() const {
+ int conn = ::accept(m_socket.fd(), NULL, NULL);
+ if (conn < 0) {
+ log_errno("Accept failed");
+ return NULL;
+ }
+ return new Connection(conn);
+}
+
+} // end namespace WDS
+
+} // end namespace android
+
+#endif
diff --git a/Source/WebKit/android/wds/Connection.h b/Source/WebKit/android/wds/Connection.h
new file mode 100644
index 0000000..d67179e
--- /dev/null
+++ b/Source/WebKit/android/wds/Connection.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WDS_CONNECTION_H
+#define WDS_CONNECTION_H
+
+#include <unistd.h>
+#include <sys/socket.h>
+
+namespace android {
+
+namespace WDS {
+
+class Socket {
+public:
+ Socket(): m_fd(-1) {}
+ Socket(int fd): m_fd(fd) {}
+ ~Socket() {
+ if (m_fd != -1) {
+ shutdown(m_fd, SHUT_RDWR);
+ close(m_fd);
+ }
+ }
+ // Open a new socket using PF_INET and SOCK_STREAM
+ bool open();
+ int fd() const { return m_fd; }
+private:
+ int m_fd;
+};
+
+class Connection {
+public:
+ Connection(int conn): m_socket(conn) {}
+ int read(char buf[], size_t length) const {
+ return recv(m_socket.fd(), buf, length, 0);
+ }
+ int write(const char buf[], size_t length) const {
+ return send(m_socket.fd(), buf, length, 0);
+ }
+ int write(const char buf[]) const {
+ return write(buf, strlen(buf));
+ }
+private:
+ Socket m_socket;
+};
+
+class ConnectionServer {
+public:
+ ConnectionServer() {}
+
+ // Establish a connection to the local host on the given port.
+ bool connect(short port);
+
+ // Blocks on the established socket until a new connection arrives.
+ Connection* accept() const;
+private:
+ Socket m_socket;
+};
+
+} // end namespace WDS
+
+} // end namespace android
+
+#endif
diff --git a/Source/WebKit/android/wds/DebugServer.cpp b/Source/WebKit/android/wds/DebugServer.cpp
new file mode 100644
index 0000000..f33a65b
--- /dev/null
+++ b/Source/WebKit/android/wds/DebugServer.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "wds"
+#include "config.h"
+
+#include "Command.h"
+#include "Connection.h"
+#include "DebugServer.h"
+#include "wtf/MainThread.h"
+#include "wtf/Threading.h"
+#include <arpa/inet.h>
+#include <cutils/properties.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+#if ENABLE(WDS)
+
+#define DEFAULT_PORT 9999
+#define log_errno(x) LOGE("%s: %d", x, strerror(errno))
+
+namespace android {
+
+namespace WDS {
+
+static DebugServer* s_server = NULL;
+
+// Main thread function for createThread
+static void* mainThread(void* v) {
+ DebugServer* server = static_cast<DebugServer*>(v);
+ server->start();
+ delete server;
+ s_server = NULL;
+ return NULL;
+}
+
+DebugServer* server() {
+ if (s_server == NULL)
+ s_server = new DebugServer();
+ return s_server;
+}
+
+DebugServer::DebugServer() {
+ // Read webcore.wds.enable to determine if the debug server should run
+ char buf[PROPERTY_VALUE_MAX];
+ int ret = property_get("webcore.wds.enable", buf, NULL);
+ if (ret != -1 && strcmp(buf, "1") == 0) {
+ LOGD("WDS Enabled");
+ m_threadId = createThread(mainThread, this, "WDS");
+ }
+ // Initialize the available commands.
+ Command::Init();
+}
+
+void DebugServer::start() {
+ LOGD("DebugServer thread started");
+
+ ConnectionServer cs;
+ if (!cs.connect(DEFAULT_PORT)) {
+ LOGE("Failed to start the server socket connection");
+ return;
+ }
+
+ while (true ) {
+ LOGD("Waiting for incoming connections...");
+ Connection* conn = cs.accept();
+ if (!conn) {
+ log_errno("Failed to accept new connections");
+ return;
+ }
+ LOGD("...Connection established");
+
+ Command* c = Command::Find(conn);
+ if (!c) {
+ LOGE("Could not find matching command");
+ delete conn;
+ } else {
+ // Dispatch the command, it will handle cleaning up the connection
+ // when finished.
+ c->dispatch();
+ }
+ }
+
+ LOGD("DebugServer thread finished");
+}
+
+} // end namespace WDS
+
+} // end namespace android
+
+#endif
diff --git a/Source/WebKit/android/wds/DebugServer.h b/Source/WebKit/android/wds/DebugServer.h
new file mode 100644
index 0000000..92edad9
--- /dev/null
+++ b/Source/WebKit/android/wds/DebugServer.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DEBUGSERVER_H
+#define DEBUGSERVER_H
+
+// Turn on the wds feature in webkit
+#define ENABLE_WDS 0
+
+#include "wtf/Threading.h"
+#include "wtf/Vector.h"
+
+// Forward declarations.
+namespace WebCore {
+ class Frame;
+}
+
+using namespace WTF;
+using namespace WebCore;
+
+namespace android {
+
+// WebCore Debug Server
+namespace WDS {
+
+class DebugServer : WTFNoncopyable::Noncopyable {
+public:
+ void start();
+ void addFrame(Frame* frame) {
+ m_frames.append(frame);
+ }
+ void removeFrame(Frame* frame) {
+ size_t i = m_frames.find(frame);
+ if (i != notFound)
+ m_frames.remove(i);
+ }
+ Frame* getFrame(unsigned idx) {
+ if (idx < m_frames.size())
+ return m_frames.at(idx);
+ return NULL;
+ }
+private:
+ DebugServer();
+ WTF::Vector<Frame*> m_frames;
+ ThreadIdentifier m_threadId;
+ friend DebugServer* server();
+};
+
+DebugServer* server();
+
+} // end namespace WDS
+
+} // end namespace android
+
+#endif
diff --git a/Source/WebKit/android/wds/client/AdbConnection.cpp b/Source/WebKit/android/wds/client/AdbConnection.cpp
new file mode 100644
index 0000000..465f9c3
--- /dev/null
+++ b/Source/WebKit/android/wds/client/AdbConnection.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "wdsclient"
+
+#include "AdbConnection.h"
+#include "ClientUtils.h"
+#include "Device.h"
+#include <arpa/inet.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+void AdbConnection::close() {
+ if (m_fd != -1) {
+ shutdown(m_fd, SHUT_RDWR);
+ ::close(m_fd);
+ m_fd = -1;
+ }
+}
+
+// Default adb port
+#define ADB_PORT 5037
+
+bool AdbConnection::connect() {
+ // Some commands (host:devices for example) close the connection so we call
+ // connect after the response.
+ close();
+
+ m_fd = socket(PF_INET, SOCK_STREAM, 0);
+ if (m_fd < 0) {
+ log_errno("Failed to create socket for connecting to adb");
+ return false;
+ }
+
+ // Create the socket address struct
+ sockaddr_in adb;
+ createTcpSocket(adb, ADB_PORT);
+
+ // Connect to adb
+ if (::connect(m_fd, (sockaddr*) &adb, sizeof(adb)) < 0) {
+ log_errno("Failed to connect to adb");
+ return false;
+ }
+
+ // Connected
+ return true;
+}
+
+// Adb protocol stuff
+#define MAX_COMMAND_LENGTH 1024
+#define PAYLOAD_LENGTH 4
+#define PAYLOAD_FORMAT "%04X"
+
+bool AdbConnection::sendRequest(const char* fmt, ...) const {
+ if (m_fd == -1) {
+ LOGE("Connection is closed");
+ return false;
+ }
+
+ // Build the command (service)
+ char buf[MAX_COMMAND_LENGTH];
+ va_list args;
+ va_start(args, fmt);
+ int res = vsnprintf(buf, MAX_COMMAND_LENGTH, fmt, args);
+ va_end(args);
+
+ LOGV("Sending command: %04X%.*s", res, res, buf);
+
+ // Construct the payload length
+ char payloadLen[PAYLOAD_LENGTH + 1];
+ snprintf(payloadLen, sizeof(payloadLen), PAYLOAD_FORMAT, res);
+
+ // First, send the payload length
+ if (send(m_fd, payloadLen, PAYLOAD_LENGTH, 0) < 0) {
+ log_errno("Failure when sending payload");
+ return false;
+ }
+
+ // Send the actual command
+ if (send(m_fd, buf, res, 0) < 0) {
+ log_errno("Failure when sending command");
+ return false;
+ }
+
+ // Check for the OKAY from adb
+ return checkOkayResponse();
+}
+
+static void printFailureMessage(int fd) {
+ // Grab the payload length
+ char lenStr[PAYLOAD_LENGTH + 1];
+ int payloadLen = recv(fd, lenStr, sizeof(lenStr) - 1, 0);
+ LOG_ASSERT(payloadLen == PAYLOAD_LENGTH, "Incorrect payload size");
+ lenStr[PAYLOAD_LENGTH] = 0;
+
+ // Parse the hex payload
+ payloadLen = strtol(lenStr, NULL, 16);
+ if (payloadLen < 0)
+ return;
+
+ // Grab the message
+ char* msg = new char[payloadLen + 1]; // include null-terminator
+ int res = recv(fd, msg, payloadLen, 0);
+ if (res < 0) {
+ log_errno("Failure reading failure message from adb");
+ return;
+ } else if (res != payloadLen) {
+ LOGE("Incorrect payload length %d - expected %d", res, payloadLen);
+ return;
+ }
+ msg[res] = 0;
+
+ // Tell somebody about it
+ LOGE("Received failure from adb: %s", msg);
+
+ // Cleanup
+ delete[] msg;
+}
+
+#define ADB_RESPONSE_LENGTH 4
+
+bool AdbConnection::checkOkayResponse() const {
+ LOG_ASSERT(m_fd != -1, "Connection has been closed!");
+
+ char buf[ADB_RESPONSE_LENGTH];
+ int res = recv(m_fd, buf, sizeof(buf), 0);
+ if (res < 0) {
+ log_errno("Failure reading response from adb");
+ return false;
+ }
+
+ // Check for a response other than OKAY/FAIL
+ if ((res == ADB_RESPONSE_LENGTH) && (strncmp(buf, "OKAY", res) == 0)) {
+ LOGV("Command OKAY");
+ return true;
+ } else if (strncmp(buf, "FAIL", ADB_RESPONSE_LENGTH) == 0) {
+ // Something happened, print out the reason for failure
+ printFailureMessage(m_fd);
+ return false;
+ }
+ LOGE("Incorrect response from adb - '%.*s'", res, buf);
+ return false;
+}
+
+void AdbConnection::clearDevices() {
+ for (unsigned i = 0; i < m_devices.size(); i++)
+ delete m_devices.editItemAt(i);
+ m_devices.clear();
+}
+
+const DeviceList& AdbConnection::getDeviceList() {
+ // Clear the current device list
+ clearDevices();
+
+ if (m_fd == -1) {
+ LOGE("Connection is closed");
+ return m_devices;
+ }
+
+ // Try to send the device list request
+ if (!sendRequest("host:devices")) {
+ LOGE("Failed to get device list from adb");
+ return m_devices;
+ }
+
+ // Get the payload length
+ char lenStr[PAYLOAD_LENGTH + 1];
+ int res = recv(m_fd, lenStr, sizeof(lenStr) - 1, 0);
+ if (res < 0) {
+ log_errno("Failure to read payload size of device list");
+ return m_devices;
+ }
+ lenStr[PAYLOAD_LENGTH] = 0;
+
+ // Parse the hex payload
+ int payloadLen = strtol(lenStr, NULL, 16);
+ if (payloadLen < 0)
+ return m_devices;
+
+ // Grab the list of devices. The format is as follows:
+ // <serialno><tab><state><newline>
+ char* msg = new char[payloadLen + 1];
+ res = recv(m_fd, msg, payloadLen, 0);
+ if (res < 0) {
+ log_errno("Failure reading the device list");
+ return m_devices;
+ } else if (res != payloadLen) {
+ LOGE("Incorrect payload length %d - expected %d", res, payloadLen);
+ return m_devices;
+ }
+ msg[res] = 0;
+
+ char serial[32];
+ char state[32];
+ int numRead;
+ char* ptr = msg;
+ while (sscanf(ptr, "%31s\t%31s\n%n", serial, state, &numRead) > 1) {
+ Device::DeviceType t = Device::DEVICE;
+ static const char emulator[] = "emulator-";
+ if (strncmp(serial, emulator, sizeof(emulator) - 1) == 0)
+ t = Device::EMULATOR;
+ LOGV("Adding device %s (%s)", serial, state);
+ m_devices.add(new Device(serial, t, this));
+
+ // Reset for the next line
+ ptr += numRead;
+ }
+ // Cleanup
+ delete[] msg;
+
+ return m_devices;
+}
diff --git a/Source/WebKit/android/wds/client/AdbConnection.h b/Source/WebKit/android/wds/client/AdbConnection.h
new file mode 100644
index 0000000..58bad67
--- /dev/null
+++ b/Source/WebKit/android/wds/client/AdbConnection.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WDS_ADB_CONNECTION_H
+#define WDS_ADB_CONNECTION_H
+
+#include "DeviceList.h"
+
+class AdbConnection {
+public:
+ AdbConnection() : m_fd(-1) {}
+ ~AdbConnection() { clearDevices(); }
+ void close();
+ bool connect();
+ bool sendRequest(const char* fmt, ...) const;
+ const DeviceList& getDeviceList();
+
+private:
+ bool checkOkayResponse() const;
+ void clearDevices();
+ DeviceList m_devices;
+ int m_fd;
+};
+
+#endif
diff --git a/Source/WebKit/android/wds/client/Android.mk b/Source/WebKit/android/wds/client/Android.mk
new file mode 100644
index 0000000..db79dd4
--- /dev/null
+++ b/Source/WebKit/android/wds/client/Android.mk
@@ -0,0 +1,39 @@
+##
+## Copyright 2008, The Android Open Source Project
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in the
+## documentation and/or other materials provided with the distribution.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+##
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ AdbConnection.cpp \
+ ClientUtils.cpp \
+ Device.cpp \
+ main.cpp
+
+LOCAL_STATIC_LIBRARIES := liblog libutils libcutils
+
+LOCAL_MODULE:= wdsclient
+
+include $(BUILD_HOST_EXECUTABLE)
diff --git a/Source/WebKit/android/wds/client/ClientUtils.cpp b/Source/WebKit/android/wds/client/ClientUtils.cpp
new file mode 100644
index 0000000..f8ca889
--- /dev/null
+++ b/Source/WebKit/android/wds/client/ClientUtils.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ClientUtils.h"
+#include <arpa/inet.h>
+#include <string.h>
+
+void createTcpSocket(sockaddr_in& addr, short port) {
+ memset(&addr, 0, sizeof(sockaddr_in));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
+}
diff --git a/Source/WebKit/android/wds/client/ClientUtils.h b/Source/WebKit/android/wds/client/ClientUtils.h
new file mode 100644
index 0000000..5da1624
--- /dev/null
+++ b/Source/WebKit/android/wds/client/ClientUtils.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WDS_CLIENT_UTILS_H
+#define WDS_CLIENT_UTILS_H
+
+#include <arpa/inet.h>
+
+/*
+ * included for sockaddr_in structure, AF_INET definiton and etc.
+ */
+#ifdef __FreeBSD__
+#include <netinet/in.h>
+#include <sys/socket.h>
+#endif
+
+// Callers need to include Log.h and errno.h to use this macro
+#define log_errno(str) LOGE("%s: %s", str, strerror(errno))
+
+// Fill in the sockaddr_in structure for binding to the localhost on the given
+// port
+void createTcpSocket(sockaddr_in& addr, short port);
+
+#endif
diff --git a/Source/WebKit/android/wds/client/Device.cpp b/Source/WebKit/android/wds/client/Device.cpp
new file mode 100644
index 0000000..789a89d
--- /dev/null
+++ b/Source/WebKit/android/wds/client/Device.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "AdbConnection.h"
+#include "Device.h"
+
+bool Device::sendRequest(const char* req) const {
+ return m_connection->sendRequest("host-serial:%s:%s", m_name, req);
+}
diff --git a/Source/WebKit/android/wds/client/Device.h b/Source/WebKit/android/wds/client/Device.h
new file mode 100644
index 0000000..39d4b12
--- /dev/null
+++ b/Source/WebKit/android/wds/client/Device.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WDS_DEVICE_H
+#define WDS_DEVICE_H
+
+#include <stdlib.h>
+
+class AdbConnection;
+
+class Device {
+public:
+ // Type of device.
+ // TODO: Add simulator support
+ enum DeviceType {
+ NONE = -1,
+ EMULATOR,
+ DEVICE
+ };
+
+ // Takes ownership of name
+ Device(char* name, DeviceType type, const AdbConnection* conn)
+ : m_connection(conn)
+ , m_name(strdup(name))
+ , m_type(type) {}
+ ~Device() { free(m_name); }
+
+ const char* name() const { return m_name; }
+ DeviceType type() const { return m_type; }
+
+ // Send a request to this device.
+ bool sendRequest(const char* req) const;
+
+private:
+ const AdbConnection* m_connection;
+ char* m_name;
+ DeviceType m_type;
+};
+
+#endif
diff --git a/Source/WebKit/android/wds/client/DeviceList.h b/Source/WebKit/android/wds/client/DeviceList.h
new file mode 100644
index 0000000..45bfb87
--- /dev/null
+++ b/Source/WebKit/android/wds/client/DeviceList.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WDS_DEVICE_LIST_H
+#define WDS_DEVICE_LIST_H
+
+#include <utils/Vector.h>
+
+class Device;
+
+typedef android::Vector<Device*> DeviceList;
+
+#endif
diff --git a/Source/WebKit/android/wds/client/main.cpp b/Source/WebKit/android/wds/client/main.cpp
new file mode 100644
index 0000000..1c7d856
--- /dev/null
+++ b/Source/WebKit/android/wds/client/main.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2008, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define LOG_TAG "wdsclient"
+
+#include "AdbConnection.h"
+#include "ClientUtils.h"
+#include "Device.h"
+#include <arpa/inet.h>
+#include <errno.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <utils/Log.h>
+
+#define DEFAULT_WDS_PORT 9999
+#define STR(x) #x
+#define XSTR(x) STR(x)
+#define PORT_STR XSTR(DEFAULT_WDS_PORT)
+
+int wds_open() {
+ // Create the structure for connecting to the forwarded 9999 port
+ sockaddr_in addr;
+ createTcpSocket(addr, DEFAULT_WDS_PORT);
+
+ // Create our socket
+ int fd = socket(PF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ log_errno("Failed to create file descriptor");
+ return -1;
+ }
+ // Connect to the remote wds server thread
+ if (connect(fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
+ log_errno("Failed to connect to remote debug server");
+ return -1;
+ }
+ return fd;
+}
+
+// Clean up the file descriptor and connections
+void wds_close(int fd) {
+ if (fd != -1) {
+ shutdown(fd, SHUT_RDWR);
+ close(fd);
+ }
+}
+
+int main(int argc, char** argv) {
+
+ Device::DeviceType type = Device::NONE;
+
+ if (argc <= 1) {
+ LOGE("wdsclient takes at least 1 argument");
+ return 1;
+ } else {
+ // Parse the options, look for -e or -d to choose a device.
+ while (true) {
+ int c = getopt(argc, argv, "ed");
+ if (c == -1)
+ break;
+ switch (c) {
+ case 'e':
+ type = Device::EMULATOR;
+ break;
+ case 'd':
+ type = Device::DEVICE;
+ break;
+ default:
+ break;
+ }
+ }
+ if (optind == argc) {
+ LOGE("No command specified");
+ return 1;
+ }
+ }
+
+ // Do the initial connection.
+ AdbConnection conn;
+ conn.connect();
+
+ const DeviceList& devices = conn.getDeviceList();
+ // host:devices closes the connection, reconnect
+ conn.connect();
+
+ // No device specified and more than one connected, bail
+ if (type == Device::NONE && devices.size() > 1) {
+ LOGE("More than one device/emulator, please specify with -e or -d");
+ return 1;
+ } else if (devices.size() == 0) {
+ LOGE("No devices connected");
+ return 1;
+ }
+
+ // Find the correct device
+ const Device* device = NULL;
+ if (type == Device::NONE)
+ device = devices[0]; // grab the only one
+ else {
+ // Search for a matching device type
+ for (unsigned i = 0; i < devices.size(); i++) {
+ if (devices[i]->type() == type) {
+ device = devices[i];
+ break;
+ }
+ }
+ }
+
+ if (!device) {
+ LOGE("No device found!");
+ return 1;
+ }
+
+ // Forward tcp:9999
+ if (!device->sendRequest("forward:tcp:" PORT_STR ";tcp:" PORT_STR)) {
+ LOGE("Failed to send forwarding request");
+ return 1;
+ }
+
+ LOGV("Connecting to localhost port " PORT_STR);
+
+ const char* command = argv[optind];
+ int commandLen = strlen(command);
+#define WDS_COMMAND_LENGTH 4
+ if (commandLen != WDS_COMMAND_LENGTH) {
+ LOGE("Commands must be 4 characters '%s'", command);
+ return 1;
+ }
+
+ // Open the wds connection
+ int wdsFd = wds_open();
+ if (wdsFd == -1)
+ return 1;
+
+ // Send the command specified
+ send(wdsFd, command, WDS_COMMAND_LENGTH, 0); // commands are 4 bytes
+
+ // Read and display the response
+ char response[256];
+ int res = 0;
+ while ((res = recv(wdsFd, response, sizeof(response), 0)) > 0)
+ printf("%.*s", res, response);
+ printf("\n\n");
+
+ // Shutdown
+ wds_close(wdsFd);
+
+ return 0;
+}