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.
5 #include "android_webview/native/aw_dev_tools_server.h"
7 #include "android_webview/native/aw_contents.h"
9 #include "base/json/json_writer.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "content/public/browser/android/devtools_auth.h"
14 #include "content/public/browser/devtools_agent_host.h"
15 #include "content/public/browser/devtools_http_handler.h"
16 #include "content/public/browser/devtools_http_handler_delegate.h"
17 #include "content/public/browser/devtools_target.h"
18 #include "content/public/browser/web_contents.h"
19 #include "jni/AwDevToolsServer_jni.h"
20 #include "net/socket/unix_domain_socket_posix.h"
21 #include "webkit/common/user_agent/user_agent_util.h"
23 using content::DevToolsAgentHost
;
24 using content::RenderViewHost
;
25 using content::WebContents
;
29 const char kFrontEndURL
[] =
30 "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
31 const char kSocketNameFormat
[] = "webview_devtools_remote_%d";
33 const char kTargetTypePage
[] = "page";
35 std::string
GetViewDescription(WebContents
* web_contents
);
37 class Target
: public content::DevToolsTarget
{
39 explicit Target(WebContents
* web_contents
);
41 virtual std::string
GetId() const OVERRIDE
{ return id_
; }
42 virtual std::string
GetType() const OVERRIDE
{ return kTargetTypePage
; }
43 virtual std::string
GetTitle() const OVERRIDE
{ return title_
; }
44 virtual std::string
GetDescription() const OVERRIDE
{ return description_
; }
45 virtual GURL
GetUrl() const OVERRIDE
{ return url_
; }
46 virtual GURL
GetFaviconUrl() const OVERRIDE
{ return GURL(); }
47 virtual base::TimeTicks
GetLastActivityTime() const OVERRIDE
{
48 return last_activity_time_
;
50 virtual bool IsAttached() const OVERRIDE
{
51 return agent_host_
->IsAttached();
53 virtual scoped_refptr
<DevToolsAgentHost
> GetAgentHost() const OVERRIDE
{
56 virtual bool Activate() const OVERRIDE
{ return false; }
57 virtual bool Close() const OVERRIDE
{ return false; }
60 scoped_refptr
<DevToolsAgentHost
> agent_host_
;
63 std::string description_
;
65 base::TimeTicks last_activity_time_
;
68 Target::Target(WebContents
* web_contents
) {
70 DevToolsAgentHost::GetOrCreateFor(web_contents
->GetRenderViewHost());
71 id_
= agent_host_
->GetId();
72 description_
= GetViewDescription(web_contents
);
73 title_
= base::UTF16ToUTF8(web_contents
->GetTitle());
74 url_
= web_contents
->GetURL();
75 last_activity_time_
= web_contents
->GetLastActiveTime();
78 // Delegate implementation for the devtools http handler for WebView. A new
79 // instance of this gets created each time web debugging is enabled.
80 class AwDevToolsServerDelegate
: public content::DevToolsHttpHandlerDelegate
{
82 AwDevToolsServerDelegate() {}
83 virtual ~AwDevToolsServerDelegate() {}
85 // DevToolsHttpProtocolHandler::Delegate overrides.
86 virtual std::string
GetDiscoveryPageHTML() OVERRIDE
;
88 virtual bool BundlesFrontendResources() OVERRIDE
{
92 virtual base::FilePath
GetDebugFrontendDir() OVERRIDE
{
93 return base::FilePath();
96 virtual std::string
GetPageThumbnailData(const GURL
&) OVERRIDE
{
100 virtual scoped_ptr
<content::DevToolsTarget
> CreateNewTarget(
101 const GURL
&) OVERRIDE
{
102 return scoped_ptr
<content::DevToolsTarget
>();
105 virtual void EnumerateTargets(TargetCallback callback
) OVERRIDE
{
107 std::vector
<RenderViewHost
*> rvh_list
=
108 DevToolsAgentHost::GetValidRenderViewHosts();
109 for (std::vector
<RenderViewHost
*>::iterator it
= rvh_list
.begin();
110 it
!= rvh_list
.end(); ++it
) {
111 WebContents
* web_contents
= WebContents::FromRenderViewHost(*it
);
113 targets
.push_back(new Target(web_contents
));
115 callback
.Run(targets
);
118 virtual scoped_ptr
<net::StreamListenSocket
> CreateSocketForTethering(
119 net::StreamListenSocket::Delegate
* delegate
,
120 std::string
* name
) OVERRIDE
{
121 return scoped_ptr
<net::StreamListenSocket
>();
125 DISALLOW_COPY_AND_ASSIGN(AwDevToolsServerDelegate
);
129 std::string
AwDevToolsServerDelegate::GetDiscoveryPageHTML() {
132 "<head><title>WebView remote debugging</title></head>"
133 "<body>Please use <a href=\'chrome://inspect\'>chrome://inspect</a>"
139 std::string
GetViewDescription(WebContents
* web_contents
) {
140 const android_webview::BrowserViewRenderer
* bvr
=
141 android_webview::AwContents::FromWebContents(web_contents
)
142 ->GetBrowserViewRenderer();
144 base::DictionaryValue description
;
145 description
.SetBoolean("attached", bvr
->IsAttachedToWindow());
146 description
.SetBoolean("visible", bvr
->IsVisible());
147 gfx::Rect screen_rect
= bvr
->GetScreenRect();
148 description
.SetInteger("screenX", screen_rect
.x());
149 description
.SetInteger("screenY", screen_rect
.y());
150 description
.SetBoolean("empty", screen_rect
.size().IsEmpty());
151 if (!screen_rect
.size().IsEmpty()) {
152 description
.SetInteger("width", screen_rect
.width());
153 description
.SetInteger("height", screen_rect
.height());
156 base::JSONWriter::Write(&description
, &json
);
162 namespace android_webview
{
164 AwDevToolsServer::AwDevToolsServer()
165 : protocol_handler_(NULL
) {
168 AwDevToolsServer::~AwDevToolsServer() {
172 void AwDevToolsServer::Start() {
173 if (protocol_handler_
)
176 protocol_handler_
= content::DevToolsHttpHandler::Start(
177 new net::UnixDomainSocketWithAbstractNamespaceFactory(
178 base::StringPrintf(kSocketNameFormat
, getpid()),
180 base::Bind(&content::CanUserConnectToDevTools
)),
181 base::StringPrintf(kFrontEndURL
,
182 webkit_glue::GetWebKitRevision().c_str()),
183 new AwDevToolsServerDelegate());
186 void AwDevToolsServer::Stop() {
187 if (!protocol_handler_
)
189 // Note that the call to Stop() below takes care of |protocol_handler_|
191 protocol_handler_
->Stop();
192 protocol_handler_
= NULL
;
195 bool AwDevToolsServer::IsStarted() const {
196 return protocol_handler_
;
199 bool RegisterAwDevToolsServer(JNIEnv
* env
) {
200 return RegisterNativesImpl(env
);
203 static jint
InitRemoteDebugging(JNIEnv
* env
,
205 AwDevToolsServer
* server
= new AwDevToolsServer();
206 return reinterpret_cast<jint
>(server
);
209 static void DestroyRemoteDebugging(JNIEnv
* env
, jobject obj
, jint server
) {
210 delete reinterpret_cast<AwDevToolsServer
*>(server
);
213 static void SetRemoteDebuggingEnabled(JNIEnv
* env
,
217 AwDevToolsServer
* devtools_server
=
218 reinterpret_cast<AwDevToolsServer
*>(server
);
220 devtools_server
->Start();
222 devtools_server
->Stop();
226 } // namespace android_webview