Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / shell / browser / shell_devtools_frontend.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/shell/browser/shell_devtools_frontend.h"
6
7 #include "base/command_line.h"
8 #include "base/json/json_reader.h"
9 #include "base/path_service.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "content/public/browser/devtools_http_handler.h"
14 #include "content/public/browser/render_frame_host.h"
15 #include "content/public/browser/render_view_host.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/common/content_client.h"
18 #include "content/shell/browser/shell.h"
19 #include "content/shell/browser/shell_browser_context.h"
20 #include "content/shell/browser/shell_browser_main_parts.h"
21 #include "content/shell/browser/shell_content_browser_client.h"
22 #include "content/shell/browser/shell_devtools_delegate.h"
23 #include "content/shell/browser/webkit_test_controller.h"
24 #include "content/shell/common/shell_switches.h"
25 #include "net/base/filename_util.h"
26
27 namespace content {
28
29 // DevTools frontend path for inspector LayoutTests.
30 GURL GetDevToolsPathAsURL(const std::string& settings,
31                           const std::string& frontend_url) {
32   if (!frontend_url.empty())
33     return GURL(frontend_url);
34   base::FilePath dir_exe;
35   if (!PathService::Get(base::DIR_EXE, &dir_exe)) {
36     NOTREACHED();
37     return GURL();
38   }
39 #if defined(OS_MACOSX)
40   // On Mac, the executable is in
41   // out/Release/Content Shell.app/Contents/MacOS/Content Shell.
42   // We need to go up 3 directories to get to out/Release.
43   dir_exe = dir_exe.AppendASCII("../../..");
44 #endif
45   base::FilePath dev_tools_path = dir_exe.AppendASCII(
46       "resources/inspector/devtools.html");
47
48   GURL result = net::FilePathToFileURL(dev_tools_path);
49   if (!settings.empty())
50       result = GURL(base::StringPrintf("%s?settings=%s&experiments=true",
51                                        result.spec().c_str(),
52                                        settings.c_str()));
53   return result;
54 }
55
56 // static
57 ShellDevToolsFrontend* ShellDevToolsFrontend::Show(
58     WebContents* inspected_contents) {
59   return ShellDevToolsFrontend::Show(inspected_contents, "", "");
60 }
61
62 // static
63 ShellDevToolsFrontend* ShellDevToolsFrontend::Show(
64     WebContents* inspected_contents,
65     const std::string& settings,
66     const std::string& frontend_url) {
67   scoped_refptr<DevToolsAgentHost> agent(
68       DevToolsAgentHost::GetOrCreateFor(inspected_contents));
69   Shell* shell = Shell::CreateNewWindow(inspected_contents->GetBrowserContext(),
70                                         GURL(),
71                                         NULL,
72                                         MSG_ROUTING_NONE,
73                                         gfx::Size());
74   ShellDevToolsFrontend* devtools_frontend = new ShellDevToolsFrontend(
75       shell,
76       agent.get());
77
78   ShellDevToolsDelegate* delegate = ShellContentBrowserClient::Get()->
79       shell_browser_main_parts()->devtools_delegate();
80   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
81     shell->LoadURL(GetDevToolsPathAsURL(settings, frontend_url));
82   else
83     shell->LoadURL(delegate->devtools_http_handler()->GetFrontendURL());
84
85   return devtools_frontend;
86 }
87
88 void ShellDevToolsFrontend::Activate() {
89   frontend_shell_->ActivateContents(web_contents());
90 }
91
92 void ShellDevToolsFrontend::Focus() {
93   web_contents()->Focus();
94 }
95
96 void ShellDevToolsFrontend::InspectElementAt(int x, int y) {
97   agent_host_->InspectElement(x, y);
98 }
99
100 void ShellDevToolsFrontend::Close() {
101   frontend_shell_->Close();
102 }
103
104 ShellDevToolsFrontend::ShellDevToolsFrontend(Shell* frontend_shell,
105                                              DevToolsAgentHost* agent_host)
106     : WebContentsObserver(frontend_shell->web_contents()),
107       frontend_shell_(frontend_shell),
108       agent_host_(agent_host) {
109 }
110
111 ShellDevToolsFrontend::~ShellDevToolsFrontend() {
112 }
113
114 void ShellDevToolsFrontend::RenderViewCreated(
115     RenderViewHost* render_view_host) {
116   if (!frontend_host_) {
117     frontend_host_.reset(DevToolsFrontendHost::Create(render_view_host, this));
118     agent_host_->AttachClient(this);
119   }
120 }
121
122 void ShellDevToolsFrontend::DocumentOnLoadCompletedInMainFrame() {
123   web_contents()->GetMainFrame()->ExecuteJavaScript(
124       base::ASCIIToUTF16("InspectorFrontendAPI.setUseSoftMenu(true);"));
125 }
126
127 void ShellDevToolsFrontend::WebContentsDestroyed() {
128   agent_host_->DetachClient();
129   delete this;
130 }
131
132 void ShellDevToolsFrontend::RenderProcessGone(base::TerminationStatus status) {
133   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
134     WebKitTestController::Get()->DevToolsProcessCrashed();
135 }
136
137 void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontend(
138     const std::string& message) {
139   std::string method;
140   std::string browser_message;
141   int id = 0;
142
143   base::ListValue* params = NULL;
144   base::DictionaryValue* dict = NULL;
145   scoped_ptr<base::Value> parsed_message(base::JSONReader::Read(message));
146   if (!parsed_message ||
147       !parsed_message->GetAsDictionary(&dict) ||
148       !dict->GetString("method", &method) ||
149       !dict->GetList("params", &params)) {
150     return;
151   }
152
153   if (method != "sendMessageToBrowser" ||
154       params->GetSize() != 1 ||
155       !params->GetString(0, &browser_message)) {
156     return;
157   }
158   dict->GetInteger("id", &id);
159
160   agent_host_->DispatchProtocolMessage(browser_message);
161
162   if (id) {
163     std::string code = "InspectorFrontendAPI.embedderMessageAck(" +
164         base::IntToString(id) + ",\"\");";
165     base::string16 javascript = base::UTF8ToUTF16(code);
166     web_contents()->GetMainFrame()->ExecuteJavaScript(javascript);
167   }
168 }
169
170 void ShellDevToolsFrontend::HandleMessageFromDevToolsFrontendToBackend(
171     const std::string& message) {
172   agent_host_->DispatchProtocolMessage(message);
173 }
174
175 void ShellDevToolsFrontend::DispatchProtocolMessage(
176     DevToolsAgentHost* agent_host, const std::string& message) {
177   std::string code = "InspectorFrontendAPI.dispatchMessage(" + message + ");";
178   base::string16 javascript = base::UTF8ToUTF16(code);
179   web_contents()->GetMainFrame()->ExecuteJavaScript(javascript);
180 }
181
182 void ShellDevToolsFrontend::AgentHostClosed(
183     DevToolsAgentHost* agent_host, bool replaced) {
184   frontend_shell_->Close();
185 }
186
187 }  // namespace content