• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2008, The Android Open Source Project
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #define LOG_TAG "wds"
27 #include "config.h"
28 
29 #include "AndroidLog.h"
30 #include "Command.h"
31 #include "Connection.h"
32 #include "DebugServer.h"
33 #include "Frame.h"
34 #include "RenderTreeAsText.h"
35 #include "RenderView.h"
36 #include "WebViewCore.h"
37 #include <utils/Log.h>
38 #include <wtf/text/CString.h>
39 
40 #if ENABLE(WDS)
41 
42 using namespace WebCore;
43 
44 namespace android {
45 
46 namespace WDS {
47 
48 //------------------------------------------------------------------------------
49 // Actual commands -- XXX should be moved somewhere else
50 //------------------------------------------------------------------------------
callDumpRenderTree(const Frame * frame,const Connection * conn)51 static bool callDumpRenderTree(const Frame* frame, const Connection* conn) {
52     CString str = externalRepresentation(frame->contentRenderer()).latin1();
53     conn->write(str.data(), str.length());
54     return true;
55 }
56 
callDumpDomTree(const Frame * frame,const Connection * conn)57 static bool callDumpDomTree(const Frame* frame, const Connection* conn) {
58     WebViewCore::getWebViewCore(frame->view())->dumpDomTree(true);
59 
60     FILE* f = fopen(DOM_TREE_LOG_FILE, "r");
61     if (!f) {
62         conn->write("Dom tree written to logcat\n");
63     } else {
64         char buf[512];
65         while (true) {
66             int nread = fread(buf, 1, sizeof(buf), f);
67             if (nread <= 0)
68                 break;
69             conn->write(buf, nread);
70         }
71         fclose(f);
72     }
73     return true;
74 }
75 
76 class WebCoreHandler : public Handler {
77 public:
post(TargetThreadFunction func,void * v) const78     virtual void post(TargetThreadFunction func, void* v) const {
79         callOnMainThread(func, v);
80     }
81 };
82 static WebCoreHandler s_webcoreHandler;
83 
84 //------------------------------------------------------------------------------
85 // End command section
86 //------------------------------------------------------------------------------
87 
88 class InternalCommand : public Command {
89 public:
InternalCommand(const Command * comm,const Frame * frame,const Connection * connection)90     InternalCommand(const Command* comm, const Frame* frame,
91             const Connection* connection)
92         : Command(*comm)
93         , m_frame(frame)
94         , m_connection(connection) {}
~InternalCommand()95     virtual ~InternalCommand() { delete m_connection; }
96 
doCommand() const97     void doCommand() const {
98         ALOGD("Executing command '%s' (%s)", m_name, m_description);
99         if (!m_dispatch(m_frame, m_connection))
100             // XXX: Have useful failure messages
101             m_connection->write("EPIC FAIL!\n", 11);
102     }
103 
104 private:
105     const Frame* m_frame;
106     const Connection* m_connection;
107 };
108 
commandDispatcher(void * v)109 static void commandDispatcher(void* v) {
110     InternalCommand* c = static_cast<InternalCommand*>(v);
111     c->doCommand();
112     delete c;
113 }
114 
dispatch()115 void Command::dispatch() {
116     m_handler.post(commandDispatcher, this);
117 }
118 
119 Vector<const Command*>* Command::s_commands;
120 
Init()121 void Command::Init() {
122     // Do not initialize twice.
123     if (s_commands)
124         return;
125     // XXX: Move this somewhere else.
126     s_commands = new Vector<const Command*>();
127     s_commands->append(new Command("DDOM", "Dump Dom Tree",
128                 callDumpDomTree, s_webcoreHandler));
129     s_commands->append(new Command("DDRT", "Dump Render Tree",
130                 callDumpRenderTree, s_webcoreHandler));
131 }
132 
Find(const Connection * conn)133 Command* Command::Find(const Connection* conn) {
134     char buf[COMMAND_LENGTH];
135     if (conn->read(buf, sizeof(buf)) != COMMAND_LENGTH)
136         return NULL;
137 
138     // Linear search of commands. TODO: binary search when more commands are
139     // added.
140     Vector<const Command*>::const_iterator i = s_commands->begin();
141     Vector<const Command*>::const_iterator end = s_commands->end();
142     while (i != end) {
143         if (strncmp(buf, (*i)->name(), sizeof(buf)) == 0)
144             return new InternalCommand(*i, server()->getFrame(0), conn);
145         i++;
146     }
147     return NULL;
148 }
149 
150 } // end namespace WDS
151 
152 } // end namespace android
153 
154 #endif
155